Javascript-форум (https://javascript.ru/forum/)
-   Мобильный JavaScript (https://javascript.ru/forum/mobile/)
-   -   URIError: malformed URI sequence (https://javascript.ru/forum/mobile/34244-urierror-malformed-uri-sequence.html)

Urfin 26.12.2012 03:37

URIError: malformed URI sequence
 
Всем привет.
Делаю сайт мобильный на jquery.mobile 1.2.0.
И столкнулся с такой проблемой.
Когда запускаю поиск по сайту и в Get параметры уходит слово прошедшее через urlencode, перестает работать кнопка назад в браузере.
Генерится ошибка URIError: malformed URI sequence.
Урл выглядит примерно так:
/search/index.php?q=%EC%EE%EB%EE%F2%EE%EA&s=y
Погуглив, я нашел объяснение, что скрипт ругается на знак процента в урле. Но как решить эту проблему так и не понятно.
Никто не сталкивался?

Deff 26.12.2012 04:22

Цитата:

Сообщение от Urfin
Погуглив, я нашел объяснение, что скрипт ругается на знак процента в урле.

Что за скрипт ?

tenshi 26.12.2012 11:50

console.log( decodeURIComponent('%EC%EE%EB%EE%F2%EE%EA') )


[telepat]нужно поставить mbstring[/telepat]

Urfin 26.12.2012 11:56

Глючит скрипт jquery.mobile.1.2.0.js
в строчке 3159:
//if the url is in the stack, it's a forward or a back
if ( decodeURIComponent( opts.currentUrl ) === decodeURIComponent( historyEntry.url ) ) {
//define back and forward by whether url is older or newer than current page
back = i < urlHistory.activeIndex;
forward = !back;
newActiveIndex = i;
}

tenshi 26.12.2012 14:07

это не скрипт глючит а ссылки у тебя кривые

Urfin 26.12.2012 15:47

Цитата:

Сообщение от tenshi (Сообщение 223581)
это не скрипт глючит а ссылки у тебя кривые

Подскажи плиз как исправить.
Если в urlencode передаются русские фразы, то в такой вид они конвертятся, с %.
Ты говоришь mbstring нужно ставить.
А можно поподробнее пояснить что к чему?
Вот какие настройки php сейчас у меня.

tenshi 26.12.2012 16:01

чувствую надо включить mbstring.func_overload
или не хватает модификатора U в регулярках

проблема в том, что у тебя строка разрезана по середине русского символа, который в utf-8 состоит из 2 байт.

Urfin 26.12.2012 16:46

Цитата:

Сообщение от tenshi (Сообщение 223608)
чувствую надо включить mbstring.func_overload
или не хватает модификатора U в регулярках

проблема в том, что у тебя строка разрезана по середине русского символа, который в utf-8 состоит из 2 байт.

Установил mbstring.func_overload = 2, но не помогло.
У меня сайт вообще в кодировке "windows-1251".
Вобщем пока решил ситуацию таким способом. Отказался от обработки строки функцией urlencode. Вместо нее пробелы в строке заменяю плюсами и передаю такую строку в поиск. Так вроде пока работает.

$q = preg_replace("/(\s+)/", "+", trim($q));

tenshi 27.12.2012 01:44

не важно в какой кодировке сайт. формы по дефолту посылают данные в utf-8

Urfin 27.12.2012 02:20

Цитата:

Сообщение от Urfin (Сообщение 223632)
Вобщем пока решил ситуацию таким способом. Отказался от обработки строки функцией urlencode. Вместо нее пробелы в строке заменяю плюсами и передаю такую строку в поиск. Так вроде пока работает.

$q = preg_replace("/(\s+)/", "+", trim($q));

К сожалению этот костылек не универсален. При наличии в воводе постраничной навигации при переходе на следующую страницу урл по умолчанию urlencod-ится и проблема с % в строке запроса снова всплывает. Даже пока не знаю как раскрутить.

nSauk 04.02.2013 18:05

Сегодня толкнулся с этим же исключением и не знаю, как найти выход.

Специфика у меня такая: от сервера API приходит текст сообщения. Чтобы сделать ссылки в этом сообщении кликабельными, я прогоняю текст через парсер, который помимо основной задачи делает ссылки читабельными с помощью decodeURIComponent — для размещения их текста внутри <a></a>. Порой сайт (VK) обрезает ссылки не в том месте, и из-за исключения работа парсера рушится.

Можно ли как-то исправить положение? Отказываться от превращения читабельных ссылок в обычные не хочется, сам VK с этим ведь как-то справляется. Можно ли проверить валидность ссылки для decodeURIComponent ещё до вызова? Дописать/обрезать её так, чтобы всё работало? Применять unescape нельзя, т.к. везде кириллица.

UPD через час
Пока решил через try..catch, но если кто-то знает решение, позволяющее модифицировать URI до валидного состояния (чтобы можно было парсить), напишите здесь, пожалуйста.

UPD2 через 7 часов
Читал документацию ES5, не совсем осилил, и придумал вот что:
function decodeURIComponentX( str ) {
    var out = '', arr, i = 0, l, x;
    arr = str.split(/(%(?:D0|D1)%.{2})/);
    for ( l = arr.length; i < l; i++ ) {
        try {
            x = decodeURIComponent( arr[i] );
        } catch (e) {
            x = arr[i];
        }
        out += x;
    }
    return out
}

decodeURIComponentX('http://vk.com/developers.php?oid=-1&p=%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9_%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%8')

Уже куда лучше, чем пропускать негодный URI вообще. Но есть сомнения по поводу регулярки: во-первых, сейчас массив из-за неё получается своеобразный, с пустыми элементами, а во-вторых, %D0 и %D1 хватает только для кириллицы, всякие æ по-прежнему будут выпадать с ошибкой.


Часовой пояс GMT +3, время: 15:48.