Правильно ли предположить, что все, что не является зарезервированным, может / должно быть закодировано в процентах?
Нет.В RFC 3986 говорится следующее:
"В обычных условиях единственное время, когда октеты в URI кодируются в процентах, - это процесс создания URI из его составных частей.реализация определяет, какие из зарезервированных символов должны использоваться в качестве разделителей подкомпонентов, а какие можно безопасно использовать в качестве данных. "
Подразумевается, что вы решаете, какой из разделителей (т.е.<delimiter>
символов) необходимо кодировать в зависимости от контекста .Те, которые не нуждаются в кодировании, не должны кодироваться.
Например, вы не должны кодировать в процентах /
, если он появляется в компоненте пути, но вы должны кодировать его в процентах, когдаон появляется в запросе или фрагменте.
Таким образом, на самом деле символ ;
(который является членом <reserved>
, не должен автоматически кодироваться в процентах. И действительно, классы URL Java и URI выиграли 'сделать это; см. URI (...) javadoc , в частности шаг 7), чтобы узнать, как обрабатывается компонент <path>
.
Это подкрепляется этим параграфом:
"Цель зарезервированных символов - предоставить набор символов-разделителей, которые можно отличить от других данных в URI. URI, которые отличаются заменой зарезервированного символа его соответствующим октетом, закодированным в процентахне являются эквивалентными. Процентное кодирование зарезервированного символа или декодирование процентного кодированного октета, который соответствует зарезервированному символу, изменит способ интерпретации URIбольшинство приложений.Таким образом, символы в зарезервированном наборе защищены от нормализации и поэтому безопасны для использования алгоритмами, специфичными для схемы и производителя, для разграничения подкомпонентов данных в URI. "
Так что этоговорит, что URL-адрес, содержащий кодированный в процентах ;
, не совпадает с URL-адресом, содержащим необработанный ;
. И последнее предложение подразумевает, что они НЕ должны автоматически кодироваться или декодироваться в процентах.
В связи с этим возникает вопрос: почему вы хотите, чтобы ;
кодировались в процентах?
Допустим, у вас есть CMS, где люди могут создавать произвольные страницы, имеющие произвольныепути. Позже мне нужно сгенерировать ссылки href на все страницы, например, в компоненте карты сайта. Поэтому мне нужен алгоритм, чтобы узнать, какие символы экранировать. Точка с запятой должна трактоваться буквально в этом случае и должна быть экранирована.
Извините, но из этого не следует, что нужно ставить точку с запятой.
До UЧто касается спецификации RL / URI, ;
не имеет особого значения.Это может иметь особое значение для определенного веб-сервера / веб-сайта, но в целом (т.е. без специальных знаний сайта) вы не можете этого знать.
Если ;
имеет особый смысл в конкретном URI, то если вы избегаете его процентов, то вы нарушаете это значение.Например, если сайт использует ;
, чтобы разрешить добавление токена сеанса к пути, то процентное кодирование не позволит ему распознавать токен сеанса ...
Если;
- это просто символ данных, предоставляемый каким-либо клиентом, и если вы в процентах его кодируете, вы потенциально меняете значение URI.Имеет ли это значение, зависит от того, что делает сервер;то есть, является ли декодирование или нет как часть логики приложения.
Что означает знание «правильного поведения», требует глубоких знаний о том, что URI означает для конечного пользователя и / или сайта. Для этого потребуется продвинутая технология чтения мыслей. Моя рекомендация заключается в том, чтобы заставить CMS решить эту проблему, надлежащим образом избегая любых разделителей и путей URI до того, как доставит их в ваше программное обеспечение. Алгоритм обязательно будет специфичным для CMS и платформы доставки контента. Он / она будет отвечать на запросы документов, идентифицированных по URL-адресам, и ему необходимо знать, как их интерпретировать.
(Поддержка произвольных людей, использующих произвольные пути, немного сумасшедшая. Должно быть некоторые ограничения. Например, даже Windows не позволяет использовать символ разделителя файлов в компоненте имени файла. Итак, вы собираетесь иметь где-то какие-то границы. Просто нужно решить, где они должны быть.)