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

使用转义符:

escape("% +&=");

OR

使用encodeURI()/encodeURIComponent()

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

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

当前回答

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

其他回答

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

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()会。

公认的答案是好的。延伸到最后一部分:

请注意,encodeURIComponent不转义“”字符。一个普通的错误是使用它来创建html属性,例如href='MyUrl'可能会出现注射错误。如果您是从字符串,对于属性引号使用“代替”,或添加额外的编码层('可以编码为%27)。

如果您希望安全起见,也应该对百分比编码的未保留字符进行编码。

您可以使用此方法来转义它们(源代码Mozilla)

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

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

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

还要记住,它们都编码不同的字符集,并适当地选择所需的字符集。encodeURI()比encodeURIComponent()编码更少的字符,encodeURIComponent()比escape()编码的字符更少(也不同于dannyp的观点)。