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

使用转义符:

escape("% +&=");

OR

使用encodeURI()/encodeURIComponent()

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

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

当前回答

受Johann桌子的启发,我决定延长桌子。我想看看哪些ASCII字符被编码。

var ascii=“!\”#$%&'()*+,-/0123456789:;<=>?@EFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvxyz{|}~“;var编码=[];ascii.split(“”).forEach(函数(字符){var obj={char};if(char!=编码URI(char))obj.encodeURI=编码URI(字符);if(char!=encodeURIComponent(char))obj.encodeURIComponent=编码URI组件(字符);if(obj.encodeURI|| obj.encoURIComponent)编码推送(obj);});console.table(编码);

表仅显示编码字符。空单元格表示原始字符和编码字符相同。


另外,我为urlenoder()和rawurlenodes()添加了另一个表。唯一的区别似乎是空格字符的编码。

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

其他回答

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

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

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

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

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

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

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

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

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

只需自己尝试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()会。

擒纵机构()

不要使用它!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

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

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