DecodeURIComponent vs unescape, что не так с unescape?

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

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

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

Итак, каковы проблемы Unicode, которые должны иметь escape/unescape? Кто-нибудь имеет какие-либо тестовые примеры, чтобы продемонстрировать проблемы?

Ответ 1

Что я хочу знать, что не так с 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));

Ответ 2

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

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

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

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

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

Ответ 3

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

function decode() {
    var obj = document.getElementById('dencoder');
    var encoded = obj.value;
    obj.value = decodeURIComponent(encoded.replace(/\+/g,  " "));
}

Ответ 4

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

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