Замена символов кодами в строке URL

  • Михаил
  • 12 мин. на прочтение
  • 73
  • 19 Dec 2020
  • 19 Dec 2020

Процентное кодирование, также известное как кодирование URL, представляет собой метод кодирования произвольных данных в унифицированном идентификаторе ресурса (URI) с использованием только ограниченных символов US-ASCII, разрешенных в URI. Хотя это известно как кодирование URL, оно также используется в более широком смысле в основном наборе унифицированных идентификаторов ресурсов (URI), который включает в себя как унифицированный указатель ресурсов (URL), так и унифицированное имя ресурса (URN). Как таковой, он также используется при подготовке данных application/x-www-form-urlencoded типа media, как часто используется при отправке данных HTML -формы в HTTP-запросах.

Процентное кодирование в URI

Типы символов URI

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

Зарезервированных символов RFC 3986.

!#$&'()*+,/:;=?@[]

RFC 3986 Неохраняемые символы.

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789-_.~

Другие символы в URI должны быть закодированы в процентах.

Зарезервированные символы

Когда символ из зарезервированного набора ("зарезервированный символ") имеет особое значение ("зарезервированное назначение") в определенном контексте, и схема URI говорит, что необходимо использовать этот символ для какой-либо другой цели, тогда символ должен быть закодирован в процентах. Процентное кодирование зарезервированного символа включает преобразование символа в соответствующее ему байтовое значение в ASCII, а затем представление этого значения в виде пары шестнадцатеричных цифр (если есть одна шестнадцатеричная цифра, добавляется начальный ноль). Цифры, которым предшествует знак процента (%) в качестве управляющего символа, затем используются в URI вместо зарезервированного символа. (Для символа, отличного от ASCII, он обычно преобразуется в его байтовую последовательность в UTF-8, а затем каждое байтовое значение представляется, как указано выше.)

Зарезервированный символ/, например, если он используется в компоненте "путь" URI, имеет особое значение разделителя между сегментами пути. Если, согласно заданной схеме URI, /должно быть в сегменте пути, то %2F%2fв сегменте вместо raw должны использоваться три символа или /.

Зарезервированные символы после процентного кодирования

!#$%&'()*+,/:;=?@[]
%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D

Зарезервированные символы, которые не имеют зарезервированного назначения в определенном контексте, также могут быть закодированы в процентах, но семантически не отличаются от тех, которые не являются.

Например, в компоненте "запрос" URI (часть после ?символа) по/-прежнему считается зарезервированным символом, но обычно он не имеет зарезервированного назначения, если только конкретная схема URI не говорит об обратном. Символ не обязательно должен кодироваться в процентах, если у него нет зарезервированного назначения.

URI, которые отличаются только тем, кодируется ли зарезервированный символ в процентах или отображается буквально, обычно считаются неэквивалентными (обозначающими один и тот же ресурс), если только не может быть определено, что зарезервированные символы, о которых идет речь, не имеют зарезервированного назначения. Это определение зависит от правил, установленных для зарезервированных символов отдельными схемами URI.

Неохраняемые символы

Символы из неограниченного набора никогда не нужно кодировать в процентах.

URI, которые отличаются только тем, кодируется ли неохраняемый символ в процентах или отображается буквально, эквивалентны по определению, но процессоры URI на практике не всегда могут распознать эту эквивалентность. Например, потребители URI не должны относиться %41иначе Aили %7Eиначе~, но некоторые это делают. Для максимальной совместимости производителям URI не рекомендуется использовать процентное кодирование символов без сохранения.

Символ процента

Поскольку символ процента ( %) служит индикатором октетов в процентном кодировании, он должен быть в процентном кодировании, %25чтобы этот октет использовался в качестве данных в URI.

Произвольные данные

Большинство схем URI включают представление произвольных данных, таких как IP-адрес или путь к файловой системе, в качестве компонентов URI. Спецификации схемы URI должны, но часто этого не делают, обеспечивать явное сопоставление между символами URI и всеми возможными значениями данных, представленными этими символами.

Двоичные данные

С момента публикации RFC 1738 в 1994 году было указано, что схемы, которые обеспечивают представление двоичных данных в URI, должны разделять данные на 8-битные байты и кодировать каждый байт в процентах таким же образом, как указано выше.[1] Байтовое значение 0x0F, например, должно быть представлено %0F, но байтовое значение 0x41 может быть представлено A, или %41. Обычно предпочтительнее использовать некодированные символы для буквенно-цифровых и других незарегистрированных символов, поскольку это приводит к сокращению URL-адресов.

Символьные данные

Процедура процентного кодирования двоичных данных часто экстраполировалась, иногда ненадлежащим образом или без полного указания, для применения к символьным данным. В годы становления Всемирной паутины, когда речь шла о символах данных в наборе ASCII и использовании их соответствующих байтов в ASCII в качестве основы для определения последовательностей с процентным кодированием, эта практика была относительно безвредной; просто предполагалось, что символы и байты сопоставляются один к одному и являются взаимозаменяемыми. Однако потребность в представлении символов за пределами диапазона ASCII быстро росла, а схемы и протоколы URI часто не обеспечивали стандартных правил подготовки символьных данных для включения в URI. В результате веб-приложения начали использовать различные многобайтовые, с сохранением состояния и другие кодировки, не совместимые с ASCII, в качестве основы для процентного кодирования, что привело к неоднозначности и трудностям с надежной интерпретацией URI.

Например, многие схемы и протоколы URI, основанные на RFC 1738 и 2396, предполагают, что символы данных будут преобразованы в байты в соответствии с некоторой неопределенной кодировкой символов, прежде чем будут представлены в URI неохраняемыми символами или байтами в процентном кодировании. Если схема не позволяет URI предоставлять подсказку о том, какая кодировка использовалась, или если кодировка конфликтует с использованием ASCII для процентного кодирования зарезервированных и незарегистрированных символов, то URI не может быть надежно интерпретирован. Некоторые схемы вообще не учитывают кодирование и вместо этого просто предполагают, что символы данных отображаются непосредственно на символы URI, что оставляет на усмотрение реализаций решение о том, следует ли и как кодировать символы данных в процентах, которые не входят ни в зарезервированные, ни в незащищенные наборы.

Обычные символы после процентного кодирования (на основе ASCII или UTF-8)

newlinespace"%-.<>\^_`{|}~£
%0A или %0D или %0D%0A%20%22%25%2D%2E%3C%3E%5C%5E%5F%60%7B%7C%7D%7E%C2%A3%E5%86%86

Произвольные символьные данные иногда кодируются в процентах и используются в ситуациях, отличных от URI, например, для программ запутывания паролей или других системных протоколов перевода.

Текущий стандарт

Основная статья: Интернационализированный идентификатор ресурса

Общий синтаксис URI рекомендует, чтобы новые схемы URI, которые обеспечивают представление символьных данных в URI, по сути, представляли символы из неограниченного набора без перевода и преобразовывали все остальные символы в байты в соответствии с UTF-8, а затем кодировали эти значения в процентах. Это предложение было введено в январе 2005 года с публикацией RFC 3986. Схемы URI, введенные до этой даты, не затрагиваются.

В текущей спецификации не рассматривается вопрос о том, что делать с закодированными символьными данными. Например, в компьютерах символьные данные проявляются в закодированной форме на некотором уровне и, следовательно, могут обрабатываться либо как двоичные, либо как символьные данные при сопоставлении с символами URI. Предположительно, спецификации схемы URI должны учитывать эту возможность и требовать того или иного, но на практике немногие, если таковые имеются, на самом деле это делают.

Нестандартные реализации

Существует нестандартная кодировка для символов Юникода: %uxxxx, где xxxx - кодовая единица UTF-16, представленная четырьмя шестнадцатеричными цифрами. Это поведение не указано ни в одном RFC и было отклонено W3C. 13-я редакция ECMA-262 по-прежнему включает escapeфункцию, использующую этот синтаксис, которая применяет кодировку UTF-8 к строке, затем проценты экранируют результирующие байты.

Тип application/x-www-form-urlencoded

Когда данные, введенные в HTML-формы, отправляются, имена и значения полей формы кодируются и отправляются на сервер в сообщении HTTP-запроса с использованием метода GET или POST, или, исторически, по электронной почте.[3] Кодировка, используемая по умолчанию, основана на ранней версии общих правил процентного кодирования URI,[4] с рядом модификаций, таких как нормализация новой строки и замена пробелов на +вместо %20. Тип носителя данных, закодированных таким образом, является application/x-www-form-urlencoded, и в настоящее время он определен в спецификациях HTML и XForms. Кроме того, спецификация CGI содержит правила того, как веб-серверы декодируют данные этого типа и делают их доступными для приложений.

Когда данные HTML-формы отправляются в HTTP-запросе GET, они включаются в компонент запроса URI запроса, используя тот же синтаксис, описанный выше. При отправке в HTTP-запросе POST или по электронной почте данные помещаются в тело сообщения и application/x-www-form-urlencodedвключаются в заголовок типа содержимого сообщения.