对要发送到web服务器的查询字符串进行编码时-何时使用escape(),何时使用encodeURI()或encodeURIComponent():

使用转义符:

escape("% +&=");

OR

使用encodeURI()/encodeURIComponent()

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

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

当前回答

擒纵机构()

不要使用它!escape()的定义见B.2.1.1节escape,附录B的介绍文本中写道:

……本附录中规定的所有语言特征和行为都具有一个或多个不可取的特征,如果没有传统用法,将从本规范中删除。。。…程序员在编写新的ECMAScript代码时,不应使用或假设这些特性和行为的存在。。。。

行为:

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

对特殊字符进行编码,但以下字符除外:@*_+-/

代码单位值为0xFF或以下的字符的十六进制形式是两位转义序列:%xx。

对于具有较大代码单位的字符,使用四位格式%uxxxx。这在查询字符串中是不允许的(如RFC3986中定义的):

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

只有在百分号后面直接跟两个十六进制数字时才允许百分号,不允许百分号后面跟u。

encodeURI()

如果需要工作URL,请使用encodeURI。拨打此电话:

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一样,不会转义'字符。

encodeURI组件()

如果要对URL参数的值进行编码,请使用encodeURIComponent。

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

然后您可以创建所需的URL:

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

您将获得以下完整URL:

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

请注意,encodeURIComponent不转义“”字符。一个常见的错误是使用它来创建html属性,例如href='MyUrl',这可能会导致注入错误。如果要从字符串构造html,请使用“而不是”作为属性引号,或添加额外的编码层('可以编码为%27)。

有关此类型编码的详细信息,请检查:http://en.wikipedia.org/wiki/Percent-encoding

其他回答

我发现,即使在很好地掌握了各种方法的用途和功能之后,尝试各种方法也是一种很好的理智检查。

为此,我发现这个网站非常有用,可以证实我的怀疑,即我正在做一些适当的事情。它还被证明对解码encodeURIComponented字符串非常有用,这对解释来说可能相当困难。一个很棒的书签:

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

@johann echavarria答案的现代改写:

控制台日志(阵列(256).fill().map((忽略,i)=>String.fromCharCode(i)).过滤器((字符)=>encodeURI(char)!==encodeURIComponent(字符)? {字符:char,encodeURI:encodeURI(char),encodeURIComponent:encodeURIComponent(char)}:错误))

或者,如果可以使用表,请将console.log替换为console.table(以获得更漂亮的输出)。

我建议不要按原样使用这些方法中的一种。编写自己的函数来做正确的事情。

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

只需自己尝试encodeURI()和encodeURIComponent()。。。

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

输入:@#$%^&*。输出:%40%23%24%25%5E%26*。等等,你怎么了?为什么没有转换?如果您尝试执行linux命令“$string”,这肯定会导致问题。TLDR:您实际上需要fixedEncodeURIComponent()和fixedEncode URI()。长话短说。。。

何时使用encodeURI()?从不encodeURI()在括号编码方面未能遵守RFC3986。按照MDN encodeURI()文档中的定义和进一步解释,使用fixedEncodeURI(。。。

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

何时使用encodeURIComponent()?从不encodeURIComponent()在编码方面未能遵守RFC3986:!'()*. 按照MDN encodeURIComponent()文档中的定义和进一步解释,使用fixedEncodeURIComponents()。。。

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

然后,您可以使用fixedEncodeURI()对单个URL片段进行编码,而fixedEncode URIComponent()将对URL片段和连接器进行编码;或者,简单地说,fixedEncodeURI()不会编码+@?=:#;,$&(因为&和+是常见的URL运算符),但fixedEncodeURIComponent()会。

我觉得这篇文章很有启发性: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!