При кодировании строки запроса для отправки на веб-сервер - когда вы используете escape(), а когда используете encodeURI() или encodeURIComponent():
Используйте escape:
escape("% +& = ");
ИЛИ ЖЕ
используйте encodeURI () / encodeURIComponent ()
encodeURI("http://www.google.com?var1=value1&var2=value2");
encodeURIComponent("var1=value1&var2=value2");
нужно что-нибудь делать с ключом? Что, если в нем стоит знак =? (это вообще возможно?)
@Mala Я все еще новичок в веб-программировании в целом, но то, что я использовал в своем ограниченном опыте, - это кодировать ключ и значение отдельно, гарантируя, что '=' остается: var params = encodeURIComponent(key) + '=' + encodeURIComponent(value); - Может быть, кто-то еще знает способ получше.
@nedshares Я играл с этим, но, насколько я могу судить, ключ, похоже, не закодирован ... по крайней мере, не таким же образом. Может быть, наличие знака = в ключе противоречит спецификации?
Также стоит отметить, что последние реализации JavaScript предоставляют интерфейсы более высокого уровня URL и URLSearchParams для управления URL-адресами и их строками запроса.
encodeURI предназначен для кодирования уже созданной многопараметрической строки (имеет дело с пробелами, которые недопустимы в URL-адресе). encodeURIComponent кодирует значение одного параметра. Они делают больше. Но это первая мысль, которую я всегда задаю себе.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


encodeURI () - функция escape () предназначена для экранирования JavaScript, а не HTTP.
Если у меня есть URL-адрес вроде этого: var url = "http://kuler-api.adobe.com/rss/get.cfm?startIndex=0&itemsPerPage=20&timeSpan=0&listType=rating" ... И я хочу получить к нему доступ через Google Ajax API, например, var gurl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q = " + url; ... тогда мне придется использовать escape(url). encodeURI(url) не работает с такими параметрами, как кажется.
вы должны использовать ecnodeURIComponent (url)
У всех трех функций есть свои проблемы. Лучше создать свою собственную функцию, которая выполняет эту работу.
Также помните, что все они кодируют разные наборы символов, и выберите нужный вам. encodeURI () кодирует меньше символов, чем encodeURIComponent (), которая кодирует меньше (и тоже отличается от точки dannyp) символов, чем escape ().
Не используйте это!
escape() определен в разделе В.2.1.2 побег, а вводный текст приложения B говорит:
... All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. ...
... Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code....
Поведение:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape
Специальные символы кодируются за исключением: @ * _ + -. /
Шестнадцатеричная форма для символов, значение кодовой единицы которых 0xFF или меньше, представляет собой двузначную escape-последовательность: %xx.
Для символов с большей кодовой единицей используется четырехзначный формат %uxxxx. Это запрещено в строке запроса (как определено в RFC3986):
query = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / " = "
Знак процента разрешен только в том случае, если за ним непосредственно следуют две шестнадцатеричные цифры, процент, за которым следует u, не допускается.
Используйте encodeURI, если вам нужен рабочий URL. Сделайте этот звонок:
encodeURI("http://www.example.org/a file with spaces.html")
получить:
http://www.example.org/a%20file%20with%20spaces.html
Не вызывайте encodeURIComponent, так как это уничтожит URL-адрес и вернет
http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html
Обратите внимание, что encodeURI, как и encodeURIComponent, не экранирует символ '.
Используйте encodeURIComponent, если вы хотите закодировать значение параметра URL.
var p1 = encodeURIComponent("http://example.org/?a=12&b=55")
Затем вы можете создать нужный URL:
var url = "http://example.net/?param1 = " + p1 + "¶m2=99";
И вы получите этот полный URL:
http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55¶m2=99
Обратите внимание, что encodeURIComponent не экранирует символ '. Распространенной ошибкой является использование его для создания атрибутов html, таких как href='MyUrl', которые могут иметь ошибку внедрения. Если вы создаете html из строк, используйте " вместо ' для кавычек атрибутов или добавьте дополнительный уровень кодирования (' может быть закодирован как% 27).
Для получения дополнительной информации об этом типе кодирования вы можете проверить: http://en.wikipedia.org/wiki/Percent-encoding
@Francois, в зависимости от принимающего сервера, он может некорректно декодировать, как escape-код кодирует верхние символы ASCII или не-ASCII, такие как: âầẩẫấậêềểễếệ Например, класс Python FieldStorage не будет правильно декодировать указанную выше строку, если закодирован до escape.
@Francois escape () кодирует нижние 128 символов ASCII, кроме букв, цифр и *@-_+./, в то время как unescape () является обратным к escape (). Насколько я могу судить, это устаревшие функции, предназначенные для кодирования URL-адресов и все еще реализованные только для обратной совместимости. Как правило, их не следует использовать, если они не взаимодействуют с приложением / веб-сервисом и т. д., Разработанным для них.
Если, конечно, вы не пытаетесь передать URL-адрес в качестве компонента URI, в этом случае вызовите encodeURIComponent.
escape () плохо поддерживает юникод и недоступен в некоторых версиях браузеров, например. FF
Иногда он не экранирует определенные символы, такие как символ ', поэтому я использую encodeURIComponent (encodeURIComponent ($ string)). Это единственный способ сделать это?
Почему он не обрабатывает одинарные кавычки?
@Eric Он не кодирует одинарные кавычки, потому что одинарные кавычки - это вполне допустимый символ, встречающийся в URI (RFC-3986). Проблема возникает, когда вы встраиваете URI в HTML, где одинарная кавычка нет является допустимым символом. Из этого следует, что URI также должны быть «закодированы в HTML» (что заменит ' на ') перед помещением в документ HTML.
@Lee - Когда вы говорите "встроить URI в HTML",, я полагаю, вы имеете в виду назначение URI, скажем, атрибуту href или src. Например, <a href = "URI"> или <img src = "URI">.
@DavidRR, это один из тех случаев, о которых я говорю. Фактически, ' технически не является допустимым символом в обычном содержимом html-документа (хотя на практике большинство браузеров справятся с этим нормально, если он не находится внутри значения атрибута). В любом случае, чтобы быть технически правильным, весь контент (включая URI) должен быть закодирован в формате html перед размещением в любом месте атрибута html или текстового содержимого элемента html. (Очевидно, что некоторые специальные элементы, такие как разделы <script> и CDATA, освобождены от этого требования).
@Lee - Мое чтение Рекомендации W3C HTML5 указывает на то, что 'может появляется в документе HTML. Например, рассмотрим пример, приведенный в Синтаксис значения атрибута в одинарных кавычках: <input type='checkbox'>. И из Нормальные элементы: «Обычные элементы могут иметь текст, ссылки на символы, другие элементы и комментарии, но текст не должен содержать символ« <»(U + 003C) или неоднозначный амперсанд». Также см. этот ответ.
@DavidRR ' является (и всегда был) допустимым ограничителем значений атрибута вокруг в html. Конечно, " является другим допустимым ограничителем значения атрибута. Из-за этого более ранние версии HTML (или, возможно, это были просто более ранние браузеры) обрабатывали ', " и несколько других символов как зарезервированные символы, и они не обрабатывались должным образом при обнаружении в нормальном контенте. (Под «нормальным содержимым» я подразумеваю значения атрибута в, а в - текстовое содержимое элементов.) Это правда, что HTML5 (и современные браузеры) допускают любые символы в блоках CDATA, если их использование однозначно контекстуально.
@Lee - Относительно текстовое содержание элементов и атрибутов: см. этот ответ в моем вопросе Использование для '& quot; сущность в HTML. Этот вопрос касается двойной кавычки; Я считаю, что аналогичные рассуждения применимы и к одинарной кавычке. Мой вывод:<p>"Double-quoted expression"</p> и <p>'Single-quoted expression'</p> действительны. Я приглашаю вас прокомментировать или добавить свой ответ на мой упомянутый вопрос. Думаю, это было бы лучше, чем продолжать наш диалог здесь ...
@DavidRR - вообще с тобой не спорю. Я признаю, что был неправ, говоря: «' технически не является допустимым символом в любом месте HTML-содержимого». Тем не менее, я лично и напрямую столкнулся с проблемами рендеринга с использованием незакодированных кавычек в текстовое содержание html-документов, но это было давно, когда браузеры были очень плохи практически во всем, и даже основные браузеры не были строго совместимы со спецификациями. Я рад, что те дни остались позади. Когда вы встретите это в старых документах, знайте, что это было основано на реальных проблемах того времени.
@DavidRR - как просили, я опубликовал ответ в другой ветке, подробно рассказывая об этом в контексте этого вопроса.
Вы имеете в виду, что с ошибка инъекции мы могли заключать значения атрибутов HTML-тегов в одинарные кавычки?
Я вижу escape в стандартах ES3 и ES5. Почему вы говорите, что он устарел?
Я нашел эту статью поучительной: Безумие Javascript: синтаксический анализ строки запроса
Я обнаружил это, когда пытался понять, почему decodeURIComponent некорректно декодирует '+'. Вот выдержка:
String: "A + B"
Expected Query String Encoding: "A+%2B+B"
escape("A + B") = "A%20+%20B" Wrong!
encodeURI("A + B") = "A%20+%20B" Wrong!
encodeURIComponent("A + B") = "A%20%2B%20B" Acceptable, but strange
Encoded String: "A+%2B+B"
Expected Decoding: "A + B"
unescape("A+%2B+B") = "A+++B" Wrong!
decodeURI("A+%2B+B") = "A+++B" Wrong!
decodeURIComponent("A+%2B+B") = "A+++B" Wrong!
Статья, на которую вы ссылаетесь, содержит много ерунды. Мне кажется, сам автор не понял, для чего правильно используются функции ...
@Christoph Мне все кажется разумным. В частности, я согласен с ним в том, что encodeURI кажется полезным только в довольно малоизвестном пограничном случае и действительно не должен существовать. У меня есть некоторые разногласия с ним, но я не вижу в этом ничего откровенно фальшивого или идиотского. Что именно вы считаете чепухой?
Атрибут enctype элемента FORM указывает тип содержимого, используемый для кодирования набора данных формы для отправки на сервер. приложение / x-www-form-urlencoded Это тип содержимого по умолчанию. Формы, отправленные с этим типом контента, должны быть закодированы следующим образом: [...] Пробелы заменяются на «+», а [...] Неалфавитно-цифровые символы заменяются на «% HH», [...]Ссылка: HTML4 Sepc
encodeURIComponent ('A + B'). replace (/ \% 20 / g, '+') + '\ n' + decodeURIComponent ("A +% 2B + B" .replace (/ \ + / g, '% 20' ));
encodeURIComponent не кодирует -_.!~*'(), что вызывает проблемы с отправкой данных на php в строке xml.
Например: <xml><text x = "100" y = "150" value = "It's a value with single quote" />
</xml>
Общий побег с encodeURI%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E
Как видите, одинарные кавычки не кодируются. Чтобы решить проблему, я создал две функции для решения проблемы в моем проекте для URL-адреса кодирования:
function encodeData(s:String):String{
return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}
Для URL-адреса декодирования:
function decodeData(s:String):String{
try{
return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")"));
}catch (e:Error) {
}
return "";
}
Он также не использует знак # (решетка / решетка / число), который равен% 23.
@ xr280xr Что ты имеешь в виду? encodeURIComponent кодирует # до% 23 (может, в 2014 году этого не было?)
У меня есть эта функция ...
var escapeURIparam = function(url) {
if (encodeURIComponent) url = encodeURIComponent(url);
else if (encodeURI) url = encodeURI(url);
else url = escape(url);
url = url.replace(/\+/g, '%2B'); // Force the replacement of "+"
return url;
};
@ChristianVielma escape () устарел, но никогда не ссылайтесь на w3schools.com. см. w3fools.com
@Christian Vielma - Некоторые считают, что справочный материал в W3Школы - это менее противоречивый и полезный. Не все согласны с тем, что на W3Schools никогда не следует ссылаться.
W3Schools действительно имеет плохую репутацию. Конечно, они не всегда точны, но опять же, я встречал много сообщений в блогах, которые также были совершенно неправильными. Для меня иногда это отличная отправная точка - просто выучить некоторую терминологию, а затем я немного углублюсь в другие ресурсы. Самое главное, что ни один ресурс никогда не должен быть библейским, когда речь идет о подобных вещах.
Похоже, @molokoloco написал эту функцию как откат к версиям, в которых encodeURI не существует, но существует escape.
Я обнаружил, что экспериментирование с различными методами - это хорошая проверка работоспособности, даже если хорошо разбираться в их различных применениях и возможностях.
С этой целью я обнаружил, что этот сайт чрезвычайно полезен для подтверждения моих подозрений в том, что я что-то делаю надлежащим образом. Он также оказался полезным для декодирования строки с encodeURIComponent, которую может быть довольно сложно интерпретировать. Отличная закладка, чтобы иметь:
Я рекомендую не использовать один из этих методов как есть. Напишите свою собственную функцию, которая работает правильно.
MDN предоставил хороший пример кодировки URL, показанный ниже.
var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);
console.info(header);
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"
function encodeRFC5987ValueChars (str) {
return encodeURIComponent(str).
// Note that although RFC3986 reserves "!", RFC5987 does not,
// so we do not need to escape it
replace(/['()]/g, escape). // i.e., %27 %28 %29
replace(/\*/g, '%2A').
// The following are not required for percent-encoding per RFC5987,
// so we can allow for a little better readability over the wire: |`^
replace(/%(?:7C|60|5E)/g, unescape);
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
какой отличный ответ (если он совместим с Chrome Edge и firefox, не делая при этом никаких ошибок)
Разница между encodeURI() и encodeURIComponent() составляет ровно 11 символов, кодированных encodeURIComponent, но не encodeURI:

Я легко сгенерировал эту таблицу с помощью console.table в Google Chrome с помощью этого кода:
var arr = [];
for(var i=0;i<256;i++) {
var char=String.fromCharCode(i);
if (encodeURI(char)!==encodeURIComponent(char)) {
arr.push({
character:char,
encodeURI:encodeURI(char),
encodeURIComponent:encodeURIComponent(char)
});
}
}
console.table(arr);Разве этот браузер не зависит?
@bladnman encodeURI и encodeURIComponent должны работать таким образом во всех основных браузерах. Вы можете протестировать приведенный выше код в Chrome и Firefox, поскольку оба поддерживают console.table. В других браузерах (включая Firefox и Chrome) вы можете использовать следующий код: var arr=[]; for(var i=0;i<256;i++){var char=String.fromCharCode(i); if (encodeURI(char)!==encodeURIComponent(char)) console.info("character: "+char + " | encodeURI: " +encodeURI(char) + " |encodeURIComponent: " + encodeURIComponent(char) ) }
@Pacerier должен быть идентичным в разных браузерах, если исходная спецификация не слишком двусмысленна ... также см. stackoverflow.com/questions/4407599/…
МНЕ НУЖНО ГОЛОСОВАТЬ ЭТО НЕСКОЛЬКО РАЗ! К сожалению, проголосовать можно только один раз.
эй, я не вижу результатов
Небольшая сравнительная таблица Java, JavaScript и PHP.
1. Java URLEncoder.encode (using UTF8 charset)
2. JavaScript encodeURIComponent
3. JavaScript escape
4. PHP urlencode
5. PHP rawurlencode
char JAVA JavaScript --PHP---
[ ] + %20 %20 + %20
[!] %21 ! %21 %21 %21
[*] * * * %2A %2A
['] %27 ' %27 %27 %27
[(] %28 ( %28 %28 %28
[)] %29 ) %29 %29 %29
[;] %3B %3B %3B %3B %3B
[:] %3A %3A %3A %3A %3A
[@] %40 %40 @ %40 %40
[&] %26 %26 %26 %26 %26
[=] %3D %3D %3D %3D %3D
[+] %2B %2B + %2B %2B
[$] %24 %24 %24 %24 %24
[,] %2C %2C %2C %2C %2C
[/] %2F %2F / %2F %2F
[?] %3F %3F %3F %3F %3F
[#] %23 %23 %23 %23 %23
[[] %5B %5B %5B %5B %5B
[]] %5D %5D %5D %5D %5D
----------------------------------------
[~] %7E ~ %7E %7E ~
[-] - - - - -
[_] _ _ _ _ _
[%] %25 %25 %25 %25 %25
[\] %5C %5C %5C %5C %5C
----------------------------------------
char -JAVA- --JavaScript-- -----PHP------
[ä] %C3%A4 %C3%A4 %E4 %C3%A4 %C3%A4
[ф] %D1%84 %D1%84 %u0444 %D1%84 %D1%84
Для кодирования javascript предоставил три встроенные функции:
escape() - не кодирует @*/+
Этот метод устарел после ECMA 3, поэтому его следует избегать.
encodeURI() - не кодирует ~!@#$&*()=:/,;?+'
Он предполагает, что URI является полным URI, поэтому не кодирует зарезервированные символы, которые имеют особое значение в URI.
Этот метод используется, когда целью является преобразование полного URL-адреса вместо некоторого специального сегмента URL-адреса.
Пример - encodeURI('http://stackoverflow.com');
даст - http://stackoverflow.com
encodeURIComponent() - не кодирует - _ . ! ~ * ' ( )
Эта функция кодирует компонент универсального идентификатора ресурса (URI), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку символа UTF-8. Этот метод следует использовать для преобразования компонента URL. Например, необходимо добавить некоторый пользовательский ввод
Пример - encodeURIComponent('http://stackoverflow.com');
даст - http% 3A% 2F% 2Fstackoverflow.com
Вся эта кодировка выполняется в UTF 8, т.е. символы будут преобразованы в формат UTF-8.
encodeURIComponent отличается от encodeURI тем, что кодирует зарезервированные символы и числовой знак # encodeURI
Принятый ответ хорош. Чтобы продолжить последнюю часть:
Note that encodeURIComponent does not escape the ' character. A common bug is to use it to create html attributes such as href='MyUrl', which could suffer an injection bug. If you are constructing html from strings, either use " instead of ' for attribute quotes, or add an extra layer of encoding (' can be encoded as %27).
Если вы хотите быть в безопасности, процент кодирования незарезервированных символов также следует закодировать.
Вы можете использовать этот метод, чтобы избежать их (источник Mozilla)
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
// fixedEncodeURIComponent("'") --> "%27"
Современная переработка ответа @johann-echavarria:
console.info(
Array(256)
.fill()
.map((ignore, i) => String.fromCharCode(i))
.filter(
(char) =>
encodeURI(char) !== encodeURIComponent(char)
? {
character: char,
encodeURI: encodeURI(char),
encodeURIComponent: encodeURIComponent(char)
}
: false
)
)Или, если вы можете использовать таблицу, замените console.info на console.table (для более красивого вывода).
Вдохновленный Стол Иоганна, я решил расширить таблицу. Я хотел посмотреть, какие символы ASCII кодируются.
var ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
var encoded = [];
ascii.split("").forEach(function (char) {
var obj = { char };
if (char != encodeURI(char))
obj.encodeURI = encodeURI(char);
if (char != encodeURIComponent(char))
obj.encodeURIComponent = encodeURIComponent(char);
if (obj.encodeURI || obj.encodeURIComponent)
encoded.push(obj);
});
console.table(encoded);В таблице показаны только закодированные символы. Пустые ячейки означают, что исходный и закодированный символы совпадают.
Чтобы быть дополнительным, я добавляю еще одну таблицу для urlencode() vs rawurlencode(). Единственная разница, похоже, заключается в кодировке символа пробела.
<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 1);
$encoded = [];
foreach ($ascii as $char) {
$obj = ["char" => $char];
if ($char != urlencode($char))
$obj["urlencode"] = urlencode($char);
if ($char != rawurlencode($char))
$obj["rawurlencode"] = rawurlencode($char);
if (isset($obj["rawurlencode"]) || isset($obj["rawurlencode"]))
$encoded[] = $obj;
}
echo "var encoded = " . json_encode($encoded) . ";";
?>
console.table(encoded);
</script>
Попробуйте сами encodeURI() и encodeURIComponent() ...
console.info(encodeURIComponent('@#$%^&*'));Ввод: @#$%^&*. Выход: %40%23%24%25%5E%26*. Итак, подождите, что случилось с *? Почему это не было обращено? Это определенно может вызвать проблемы, если вы попытаетесь сделать linux command "$string". TL; DR: вам действительно нужны fixedEncodeURIComponent() и fixedEncodeURI(). Длинная история...
Когда использовать encodeURI()? Никогда. encodeURI() не соответствует RFC3986 в отношении кодирования скобок. Используйте fixedEncodeURI(), как определено и более подробно описано в Документация MDN encodeURI () ...
function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); }
Когда использовать encodeURIComponent()? Никогда. encodeURIComponent() не соответствует RFC3986 в отношении кодировки: !'()*. Используйте fixedEncodeURIComponent(), как определено и подробно описано в Документация MDN encodeURIComponent () ...
function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }
Затем вы можете использовать fixedEncodeURI() для кодирования одного фрагмента URL, тогда как fixedEncodeURIComponent() будет кодировать фрагменты URL и соединители; или просто fixedEncodeURI() не будет кодировать +@?=:#;,$& (поскольку & и + являются общими операторами URL), но fixedEncodeURIComponent() будет.
Стоит отметить, что
encodeURIComponent("var1=value1&var2=value2")является типичным вариантом использования нет. Этот пример будет кодировать=и&, что, вероятно, не то, что было задумано!encodeURIComponentобычно применяется отдельно только к значению в каждой паре значений ключа (часть после каждого=).