简体   繁体   English

你什么时候应该使用escape而不是encodeURI / encodeURIComponent?

[英]When are you supposed to use escape instead of encodeURI / encodeURIComponent?

When encoding a query string to be sent to a web server - when do you use escape() and when do you use encodeURI() or encodeURIComponent() :编码要发送到 Web 服务器的查询字符串时 - 何时使用escape()以及何时使用encodeURI()encodeURIComponent()

Use escape:使用转义:

escape("% +&=");

OR或者

use encodeURI() / encodeURIComponent()使用 encodeURI() / encodeURIComponent()

encodeURI("http://www.google.com?var1=value1&var2=value2");

encodeURIComponent("var1=value1&var2=value2");

escape()逃脱()

Don't use it!不要使用它! escape() is defined in section B.2.1.2 escape and the introduction text of Annex B says: escape()在第B.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.... ...程序员在编写新的 ECMAScript 代码时不应使用或假设这些功能和行为的存在......

Behaviour:行为:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape

Special characters are encoded with the exception of: @*_+-./特殊字符编码除外:@*_+-./

The hexadecimal form for characters, whose code unit value is 0xFF or less, is a two-digit escape sequence: %xx .编码单元值为 0xFF 或更小的字符的十六进制形式是一个两位数的转义序列: %xx

For characters with a greater code unit, the four-digit format %uxxxx is used.对于具有更大代码单元的字符,使用四位格式%uxxxx This is not allowed within a query string (as defined in RFC3986 ):这在查询字符串中是不允许的(如RFC3986 中所定义):

query       = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

A percent sign is only allowed if it is directly followed by two hexdigits, percent followed by u is not allowed.百分号只在后面直接跟两个十六进制数字时才允许,百分比后面跟u是不允许的。

encodeURI()编码URI()

Use encodeURI when you want a working URL.当您需要工作 URL 时,请使用 encodeURI。 Make this call:打这个电话:

encodeURI("http://www.example.org/a file with spaces.html")

to get:要得到:

http://www.example.org/a%20file%20with%20spaces.html

Don't call encodeURIComponent since it would destroy the URL and return不要调用 encodeURIComponent 因为它会破坏 URL 并返回

http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html

Note that encodeURI, like encodeURIComponent, does not escape the ' character.请注意,encodeURI 与 encodeURIComponent 一样,不会对 ' 字符进行转义。

encodeURIComponent()编码URI组件()

Use encodeURIComponent when you want to encode the value of a URL parameter.当您想要对 URL 参数的值进行编码时,请使用 encodeURIComponent。

var p1 = encodeURIComponent("http://example.org/?a=12&b=55")

Then you may create the URL you need:然后你可以创建你需要的 URL:

var url = "http://example.net/?param1=" + p1 + "&param2=99";

And you will get this complete URL:你会得到这个完整的 URL:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=99

Note that encodeURIComponent does not escape the ' character.请注意, encodeURIComponent 不会对'字符进行转义。 A common bug is to use it to create html attributes such as href='MyUrl' , which could suffer an injection bug.一个常见的错误是使用它来创建 html 属性,例如href='MyUrl' ,这可能会遭受注入错误。 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).如果您从字符串构造 html,请使用"而不是'来表示属性引号,或者添加额外的编码层( '可以编码为 %27)。

For more information on this type of encoding you can check: http://en.wikipedia.org/wiki/Percent-encoding有关此类编码的更多信息,您可以查看: http : //en.wikipedia.org/wiki/Percent-encoding

The difference between encodeURI() and encodeURIComponent() are exactly 11 characters encoded by encodeURIComponent but not by encodeURI: encodeURI()encodeURIComponent()之间的区别正好是由 encodeURIComponent 编码而不是由 encodeURI 编码的 11 个字符:

包含 encodeURI 和 encodeURIComponent 之间的十个差异的表

I generated this table easily with console.table in Google Chrome with this code:我使用以下代码在谷歌浏览器中使用console.table轻松生成了这个表:

 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);

I found this article enlightening : Javascript Madness: Query String Parsing我发现这篇文章很有启发性: Javascript Madness: Query String Parsing

I found it when I was trying to undersand why decodeURIComponent was not decoding '+' correctly.当我试图理解为什么 decodeURIComponent 没有正确解码“+”时,我发现了它。 Here is an extract:这是一个摘录:

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!

encodeURIComponent doesn't encode -_.!~*'() , causing problem in posting data to php in xml string. encodeURIComponent 不编码-_.!~*'() ,导致在 xml 字符串中将数据发布到 php 时出现问题。

For example:例如:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

General escape with encodeURI使用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

You can see, single quote is not encoded.你可以看到,单引号没有被编码。 To resolve issue I created two functions to solve issue in my project, for Encoding URL:为了解决问题,我创建了两个函数来解决我的项目中的问题,用于编码 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");
}

For Decoding URL:对于解码 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 "";
}

encodeURI() - escape() 函数用于 javascript 转义,而不是 HTTP。

Small comparison table Java vs. JavaScript vs. PHP.小型比较表 Java vs. JavaScript vs. 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

I recommend not to use one of those methods as is.我建议不要按原样使用其中一种方法。 Write your own function which does the right thing.编写自己的函数来做正确的事情。

MDN has given a good example on url encoding shown below. MDN 给出了一个很好的例子来说明如下所示的 url 编码。

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);

console.log(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 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

For the purpose of encoding javascript has given three inbuilt functions -为了编码 javascript 给出了三个内置函数 -

  1. escape() - does not encode @*/+ This method is deprecated after the ECMA 3 so it should be avoided. escape() - 不编码@*/+此方法在 ECMA 3 之后被弃用,因此应避免使用。

  2. encodeURI() - does not encode ~!@#$&*()=:/,;?+' It assumes that the URI is a complete URI, so does not encode reserved characters that have special meaning in the URI. encodeURI() - 不编码~!@#$&*()=:/,;?+'它假设 URI 是一个完整的 URI,所以不编码在 URI 中具有特殊含义的保留字符。 This method is used when the intent is to convert the complete URL instead of some special segment of URL.当意图是转换完整的 URL 而不是 URL 的某些特殊段时,使用此方法。 Example - encodeURI('http://stackoverflow.com');示例 - encodeURI('http://stackoverflow.com'); will give - http://stackoverflow.com会给 - http://stackoverflow.com

  3. encodeURIComponent() - does not encode - _ . ! ~ * ' ( ) encodeURIComponent() - 不编码- _ . ! ~ * ' ( ) - _ . ! ~ * ' ( ) - _ . ! ~ * ' ( ) This function encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. - _ . ! ~ * ' ( )此函数通过用代表字符的 UTF-8 编码的一个、两个、三个或四个转义序列替换特定字符的每个实例来对统一资源标识符 (URI) 组件进行编码。 This method should be used to convert a component of URL.该方法应该用于转换 URL 的组件。 For instance some user input needs to be appended Example - encodeURIComponent('http://stackoverflow.com');例如,需要附加一些用户输入示例 - encodeURIComponent('http://stackoverflow.com'); will give - http%3A%2F%2Fstackoverflow.com会给 - http%3A%2F%2Fstackoverflow.com

All this encoding is performed in UTF 8 ie the characters will be converted in UTF-8 format.所有这些编码都是在 UTF 8 中执行的,即字符将被转换为 UTF-8 格式。

encodeURIComponent differ from encodeURI in that it encode reserved characters and Number sign # of encodeURI encodeURIComponent 与 encodeURI 的不同之处在于它对 encodeURI 的保留字符和数字符号 # 进行编码

Also remember that they all encode different sets of characters, and select the one you need appropriately.还要记住,它们都对不同的字符集进行编码,并适当地选择您需要的字符集。 encodeURI() encodes fewer characters than encodeURIComponent(), which encodes fewer (and also different, to dannyp's point) characters than escape(). encodeURI() 编码的字符比 encodeURIComponent() 少,后者编码的字符比escape() 少(而且也不同于 dannyp 的观点)。

Just try encodeURI() and encodeURIComponent() yourself...只需自己尝试encodeURI()encodeURIComponent() ......

 console.log(encodeURIComponent('@#$%^&*'));

Input: @#$%^&* .输入: @#$%^&* Output: %40%23%24%25%5E%26* .输出: %40%23%24%25%5E%26* So, wait, what happened to * ?那么,等等, *发生了什么? Why wasn't this converted?为什么这个没有转换? It could definitely cause problems if you tried to do linux command "$string" .如果您尝试执行linux command "$string"它肯定会导致问题。 TLDR: You actually want fixedEncodeURIComponent() and fixedEncodeURI() . TLDR:您实际上需要fixedEncodeURIComponent()fixedEncodeURI() Long-story...很长的故事...

When to use encodeURI() ?何时使用encodeURI() Never.绝不。 encodeURI() fails to adhere to RFC3986 with regard to bracket-encoding. encodeURI()在括号编码方面未能遵守 RFC3986。 Use fixedEncodeURI() , as defined and further explained at the MDN encodeURI() Documentation ...使用fixedEncodeURI() ,如MDN encodeURI() 文档中定义和进一步解释的那样......

 function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); }

When to use encodeURIComponent() ?何时使用encodeURIComponent() Never.绝不。 encodeURIComponent() fails to adhere to RFC3986 with regard to encoding: !'()* . encodeURIComponent()在编码方面未能遵守 RFC3986: !'()* Use fixedEncodeURIComponent() , as defined and further explained at the MDN encodeURIComponent() Documentation ...使用fixedEncodeURIComponent() ,如MDN encodeURIComponent() 文档中定义和进一步解释的那样......

 function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }

Then you can use fixedEncodeURI() to encode a single URL piece, whereas fixedEncodeURIComponent() will encode URL pieces and connectors;然后您可以使用fixedEncodeURI()对单个 URL 片段进行编码,而fixedEncodeURIComponent()将对 URL 片段和连接器进行编码; or, simply, fixedEncodeURI() will not encode +@?=:#;,$& (as & and + are common URL operators), but fixedEncodeURIComponent() will.或者,简单地说, fixedEncodeURI()不会编码+@?=:#;,$& (因为&+是常见的 URL 运算符),但是fixedEncodeURIComponent()会。

I've found that experimenting with the various methods is a good sanity check even after having a good handle of what their various uses and capabilities are.我发现尝试各种方法是一个很好的健全性检查,即使在很好地掌握了它们的各种用途和功能之后也是如此。

Towards that end I have found this website extremely useful to confirm my suspicions that I am doing something appropriately.为此,我发现这个网站非常有用,可以证实我对我正在做的事情的怀疑。 It has also proven useful for decoding an encodeURIComponent'ed string which can be rather challenging to interpret.它也被证明对于解码一个 encodeURIComponent 的字符串很有用,这对解释来说可能相当具有挑战性。 A great bookmark to have:一个很棒的书签:

http://www.the-art-of-web.com/javascript/escape/ http://www.the-art-of-web.com/javascript/escape/

The accepted answer is good.接受的答案很好。 To extend on the last part:扩展最后一部分:

Note that encodeURIComponent does not escape the ' character.请注意, encodeURIComponent 不会转义 ' 字符。 A common bug is to use it to create html attributes such as href='MyUrl', which could suffer an injection bug.一个常见的错误是使用它来创建 html 属性,例如 href='MyUrl',这可能会遭受注入错误。 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).如果您从字符串构造 html,请使用 " 而不是 ' 来表示属性引号,或者添加额外的编码层(' 可以编码为 %27)。

If you want to be on the safe side, percent encoding unreserved characters should be encoded as well.如果您想安全起见,也应该对未保留字符的百分比编码进行编码。

You can use this method to escape them (source Mozilla )您可以使用此方法来转义它们(来源Mozilla

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

// fixedEncodeURIComponent("'") --> "%27"

Inspired by Johann's table , I've decided to extend the table.Johann 桌子的启发,我决定扩展桌子。 I wanted to see which ASCII characters get encoded.我想看看哪些 ASCII 字符被编码。

console.table 的屏幕截图

 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);

Table shows only the encoded characters.表仅显示编码字符。 Empty cells mean that the original and the encoded characters are the same.空单元格表示原始字符和编码字符相同。


Just to be extra, I'm adding another table for urlencode() vs rawurlencode() .只是为了额外,我为urlencode()rawurlencode()添加了另一个表。 The only difference seems to be the encoding of space character.唯一的区别似乎是空格字符的编码。

console.table 的屏幕截图

<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>

Modern rewrite of @johann-echavarria's answer: @johann-echavarria 答案的现代重写:

 console.log( Array(256) .fill() .map((ignore, i) => String.fromCharCode(i)) .filter( (char) => encodeURI(char) !== encodeURIComponent(char) ? { character: char, encodeURI: encodeURI(char), encodeURIComponent: encodeURIComponent(char) } : false ) )

Or if you can use a table, replace console.log with console.table (for the prettier output).或者,如果您可以使用表格,请将console.log替换为console.table (以获得更漂亮的输出)。

I have this function...我有这个功能...

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;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM