Ответ 1
encodeURIComponent
удаляет все символы, кроме следующих:
алфавитные, десятичные цифры, - _.! ~ * '()
Если вы хотите использовать кодировку, совместимую с RFC 3986 (которая резервирует !
, '
, (
, )
и *
), вы можете использовать:
function rfc3986EncodeURIComponent (str) {
return encodeURIComponent(str).replace(/[!'()*]/g, escape);
}
Вы можете получить более подробную информацию об этом в MDN.
UPDATE:
Чтобы ответить на ваш вопрос, почему '
и другие символы, упомянутые выше, не кодируются encodeURIComponent, короткий ответ заключается в том, что их нужно кодировать только в определенных схемах URI, и решение о их кодировании зависит от схемы вы используете.
Чтобы процитировать RFC 3986:
Приложения, создающие URI, должны иметь октеты данных с процентным кодированием, которые соответствуют символам в
reserved set
, если только эти символы специально разрешены схемой URI для представления данных в этом компонент. Если зарезервированный символ найден в компоненте URI и нет для этого символа известна роль разграничения, тогда она должна быть интерпретируется как представляющий октет данных, соответствующий этому кодировка символов в US-ASCII.
Где "зарезервированный набор" определяется как
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
Апостроф находится в группе sub-delims
. Другими словами, вы должны оставить эти символы незакодированными, если вы уверены, что потребляющие приложения будут знать, что с ними делать: например, если вы ошибочно закодированы ?
и &
, они больше не будут разграничивать детали запроса. Исторически было также предложение о параметрах сегмента пути, разделенных символами ;
и ,
(не получило большого значения), поэтому эти символы также разрешены. Дело не в том, что апостор "свободен в использовании" (т.е. unreserved
) в данных URI, но предполагалось, что он будет иметь какое-то особое значение в контексте URI, например, segment
part:
segment = *pchar
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"