У меня есть сообщение в блоге , в котором подробно и подробно дается ответ на этот вопрос.
Вы должны никогда использовать encodeURI
для программного создания URI, по причинам, которые вы говорите - вы всегда должны использовать encodeURIComponent
для отдельных компонентов, а затем объединять их в полный URI.
Где encodeURI
означает почти . Полезно использовать «очистку» URI в соответствии с Законом Постеля («Будьте либеральны в том, что вы принимаете, и консервативны в том, что вы отправляете» . ") Если кто-то дает вам полный URI, он может содержать недопустимые символы, такие как пробелы, определенные символы ASCII (например, двойные кавычки) и символы Unicode. encodeURI
может использоваться для преобразования этих недопустимых символов в допустимые последовательности с экранированием процентов без кодировки разделителей. Точно так же decodeURI
можно использовать для «симпатичной печати» URI, показывая последовательности с экранированием процентов в виде технически недопустимых пустых символов.
Например, URL:
http://example.com/admin/login?name=Helen Ødegård&gender=f
незаконно, но все еще совершенно однозначно. encodeURI
преобразует его в действительный URI:
http://example.com/admin/login?name=Helen%20%C3%98deg%C3%A5rd&gender=f
Примером приложения, которое может захотеть выполнить подобную «очистку URI», является веб-браузер. Когда вы вводите URL-адрес в адресную строку, он должен пытаться преобразовать любые недопустимые символы в процентные экранирования, а не просто иметь ошибку. Программное обеспечение, которое обрабатывает URI (например, HTML-скребок, который хочет получить все URL-адреса в гиперссылках на странице), также может захотеть применить этот вид очистки в случае, если какой-либо из URL-адресов технически недопустим.
К сожалению, encodeURI
имеет критическую уязвимость, заключающуюся в том, что он экранирует символы "%", что делает его абсолютно бесполезным для очистки URI (он будет дважды экранировать любой URI, который уже имеет процентные экранирования). Поэтому я позаимствовал функцию Mozilla fixedEncodeURI и улучшил ее, чтобы она корректно очищала URI:
function fixedEncodeURI(str) {
return encodeURI(str).replace(/%25/g, '%').replace(/%5B/g, '[').replace(/%5D/g, ']');
}
Так что вы всегда должны использовать encodeURIComponent
для внутреннего создания URI. Вы никогда не должны использовать encodeURI
, но вы можете использовать мой fixedEncodeURI
, чтобы попытаться «очистить» URI, которые были предоставлены из внешнего источника (обычно как часть пользовательского интерфейса).