Существуют места / библиотеки, которые, по-видимому, рассматривают символы "@" в сегменте пути URL как "специальный символ", который должен быть закодирован, и места / библиотеки, которые этого не делают.
Стандарт, для которого символы должны быть экранированы в сегменте пути: RFC 3986, Приложение A .
path = path-abempty ; begins with "/" or is empty
/ path-absolute ; begins with "/" but not "//"
/ path-noscheme ; begins with a non-colon segment
/ path-rootless ; begins with a segment
/ path-empty ; zero characters
path-abempty = *( "/" segment )
path-absolute = "/" [ segment-nz *( "/" segment ) ]
path-noscheme = segment-nz-nc *( "/" segment )
path-rootless = segment-nz *( "/" segment )
path-empty = 0<pchar>
Обратите внимание, что в зависимости от используемой вами траектории производства, существует три различных варианта сегмента
segment = *pchar
segment-nz = 1*pchar
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
; non-zero-length segment without any colon ":"
но ...
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
Так что @
разрешен в любом сегменте пути.
Это требуется? Насколько я могу судить, ответ - нет - использование pct-кодированного представления вместо этого разрешено, когда @
не выполняет роль разделителя. Там нет ничего явного, но это наблюдение о незарезервированных символах является подсказкой:
При разыменовании URI компоненты и подкомпоненты, имеющие значение для процесса разыменования для конкретной схемы (если есть), должны быть проанализированы и разделены, прежде чем октеты в этих компонентах, закодированные в процентах, могут быть безопасно декодированы, так как в противном случае данные могут быть ошибочно принят за разделители компонентов. Единственное исключение - октеты с кодированием в процентах, соответствующие символам в незарезервированном наборе, которые могут быть декодированы в любое время. Например, октет, соответствующий символу тильды ("~"), часто кодируется как "% 7E" в более старых реализациях обработки URI; «% 7E» можно заменить на «~» без изменения его интерпретации.
Это говорит о том, что pct-кодирование незарезервированных символов разрешено, хотя это явно не требуется. Так что это должно остаться в силе для других символов после того, как разделители были разрешены.
Для справки: незарезервированный набор - это почти то, что вы ожидаете.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"