decodeURIComponent против unescape, что не так с unescape? - PullRequest
46 голосов
/ 06 марта 2009

Отвечая на другой вопрос, я узнал, что мои знания Javascript / DOM устарели, поскольку я все еще использую escape / unescape для кодирования содержимого компонентов URL, тогда как, похоже, теперь мне следует вместо этого используется encodeURIComponent / decodeURIComponent.

Что я хочу знать, что не так с escape / unescape? Есть некоторые смутные предположения, что есть какие-то проблемы с символами Юникода, но я не могу найти какое-либо определенное объяснение.

Мой опыт работы с Интернетом довольно предвзят, почти все они пишут большие интранет-приложения, связанные с Internet Explorer. Это повлекло за собой широкое использование escape / unescape, и в течение многих лет соответствующие приложения полностью поддерживали Unicode.

Так какие же проблемы с Unicode должны возникнуть у escape / unescape? У кого-нибудь есть тестовые примеры для демонстрации проблем?

Ответы [ 4 ]

40 голосов
/ 06 марта 2009

Что я хочу знать, что не так с escape / unescape?

Они не «неправильны» как таковые, это просто их собственный специальный формат строки, который выглядит как кодировка URI-параметров, но на самом деле это не так. В частности:

  • ‘+’ означает плюс, а не пробел
  • существует специальный формат «% uNNNN» для кодирования кодовых точек Unicode UTF-16 вместо кодирования байтов UTF-8

Таким образом, если вы используете escape () для создания значений параметров URI, вы получите неправильные результаты для строк, содержащих плюс, или любых не-ASCII символов.

escape () может использоваться как внутренняя схема кодирования только для JavaScript, например, для экранирования значений cookie. Однако теперь, когда все браузеры поддерживают encodeURIComponent (чего изначально не было), нет никаких оснований использовать escape вместо этого.

Существует только одно современное использование для escape / unescape, о котором я знаю, и это быстрый способ реализовать кодер / декодер UTF-8, используя обработку UTF-8 в обработке URIComponent:

utf8bytes= unescape(encodeURIComponent(unicodecharacters));
unicodecharacters= decodeURIComponent(escape(utf8bytes));
9 голосов
/ 08 октября 2012

escape работает только с символами в диапазоне от 0 до 255 включительно (ISO-8859-1, который фактически представляет собой кодовые точки Unicode, представляемые одним байтом). (*)

encodeURIComponent работает для всех строк, которые может представлять javascript (который представляет собой весь диапазон базовой многоязычной плоскости Юникода, т. Е. Кодовые точки Юникода от 0 до 1 114 111 или 0x10FFFF, которые охватывают практически любую систему письма, написанную человеком).

Обе функции создают безопасные для URL строки, которые используют только кодовые точки от 0 до 127 включительно (US-ASCII), что достигается последним, сначала кодируя строку как UTF-8, а затем применяя шестнадцатеричное кодирование %XX, знакомое по * 1008. *, в любой код, который не является безопасным для URL.

Это, кстати, то, почему вы можете сделать кодировщик / декодер UTF-8 с двумя функциями в javascript без каких-либо циклов или генерации мусора, комбинируя эти примитивы для отмены всей обработки, кроме UTF-8 побочные эффекты, так как версии unescape и decodeURIComponent делают то же самое в обратном порядке.

(*) Примечание. Некоторые современные браузеры, такие как Google Chrome, были настроены для получения% uXXXX для диапазона символов выше-255, для которого первоначально не было задано escape-число, но поддержка веб-сервера для декодирования этой кодировки также не так хороша. - реализуется как декодирование стандартизированного IETF кодирования на основе UTF-8.

7 голосов
/ 16 ноября 2013

Лучший ответ - это то, что он работает онлайн на этом сайте http://meyerweb.com/eric/tools/dencoder/

function decode() {
    var obj = document.getElementById('dencoder');
    var encoded = obj.value;
    obj.value = decodeURIComponent(encoded.replace(/\+/g,  " "));
}
5 голосов
/ 11 октября 2011

Другое «современное» использование, с которым я столкнулся, - анализ строки в кодировке URI, которая может содержать недопустимые последовательности байтов UTF8. В некоторых случаях decodeURIComponent может выдать исключение. Возможно, вам придется перехватить это исключение и вернуться к использованию unescape.

Примером может быть 'tür', закодированный как 't% FCr', который я видел в Firefox (когда символы вставляются в адресную строку после?).

...