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

Ada*_*dam 1371 javascript encoding query-string

编码要发送到Web服务器的查询字符串时 - 何时使用escape()以及何时使用encodeURI()encodeURIComponent():

使用转义:

escape("% +&=");
Run Code Online (Sandbox Code Playgroud)

要么

使用encodeURI()/ encodeURIComponent()

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

encodeURIComponent("var1=value1&var2=value2");
Run Code Online (Sandbox Code Playgroud)

Arn*_*son 1891

逃逸()

不要用它! escape()B.2.1.2节中规定了逃逸,附件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    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="
Run Code Online (Sandbox Code Playgroud)

仅当百分号直接后跟两个十六进制数字时才允许百分号,u不允许使用百分号.

是encodeURI()

如果需要工作URL,请使用encodeURI.拨打这个电话:

encodeURI("http://www.example.org/a file with spaces.html")
Run Code Online (Sandbox Code Playgroud)

要得到:

http://www.example.org/a%20file%20with%20spaces.html
Run Code Online (Sandbox Code Playgroud)

不要调用encodeURIComponent,因为它会破坏URL并返回

http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html
Run Code Online (Sandbox Code Playgroud)

encodeURIComponent方法()

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

var p1 = encodeURIComponent("http://example.org/?a=12&b=55")
Run Code Online (Sandbox Code Playgroud)

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

var url = "http://example.net/?param1=" + p1 + "&param2=99";
Run Code Online (Sandbox Code Playgroud)

您将获得这个完整的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

  • @Francois,取决于接收服务器,它可能无法正确解码转义编码高位ASCII或非ASCII字符的方式,例如:ầẩẫấậêềểễếệ例如,如果编译了bye escape,Python的FieldStorage类将无法正确解码上述字符串. (31认同)
  • @Francois escape()编码除字母,数字和*@-_+./之外的低128个ASCII字符,而unescape()是escape()的反转.据我所知,它们是为编码URL而设计的遗留功能,但仍然是为了向后兼容而实现的.通常,除非与为其设计的app/web服务/等交互,否则不应使用它们. (22认同)
  • @Eric它不对单引号进行编码,因为单引号是在URI中发生的完全有效的字符([RFC-3986](http://tools.ietf.org/html/rfc3986#section-2.2)) .在HTML中嵌入URI时会出现问题,其中单引号*不是*有效字符.接下来,在放入HTML文档之前,URI也应该是"HTML编码的"(它将用'''替换`'`). (10认同)
  • 当然,除非您尝试将URL作为URI组件传递,否则调用encodeURIComponent. (3认同)
  • 为什么不处理单引号? (3认同)
  • @DavidRR是我所指的案例之一.实际上,```在技术上并不是html文档正常内容中的任何有效字符(尽管在实践中,大多数浏览器只要不在属性值内就能很好地处理它).无论如何,为了在技术上正确,所有内容(包括URI)在被放置在html属性中的任何位置或html元素的文本内容之前应该进行html编码.(显然,某些特殊元素,如`<script>`和CDATA部分可以免除此要求). (2认同)
  • @DavidRR - 根本不和你争论.我承认我说错了,"`'`在技术上并不是HTML内容中的任何有效字符".也就是说,我个人直接在html文档的**文本内容**中使用未编码的引号时遇到了渲染问题,但是很久以前,当浏览器基本上都是非常糟糕的时候,甚至主流浏览器都没有严格规格兼容.我很高兴我们离开那些日子.当您在旧文档中遇到此问题时,请知道它是基于当时的实际现实问题. (2认同)
  • 你的意思是*注入bug*,我们可以将HTML标签属性值括在单引号中吗? (2认同)

Joh*_*ria 428

encodeURI()和之间的差异encodeURIComponent()正好是由encodeURIComponent编码的11个字符,而不是encodeURI编码的:

表与encodeURI和encodeURIComponent之间的十个区别

我使用以下代码在Google Chrome中使用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);
Run Code Online (Sandbox Code Playgroud)

  • +1表示清晰,另一个表示console.table魔法! (121认同)
  • @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.log("character:"+ char +"| encodeURI:"+ encodeURI(char)+"| encodeURIComponent:"+ encodeURIComponent(char))}` (4认同)
  • 我需要突破这几个时代!不幸的是只能投票一次. (2认同)

Dam*_*ien 45

我发现这篇文章很有启发性: Javascript Madness:Query String Parsing

当我试图解释为什么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!
Run Code Online (Sandbox Code Playgroud)

  • 你链接的文章包含很多废话.在我看来,作者自己并不明白这些功能是否适用于...... (10认同)
  • decodeURIComponent("A +%2B + B".replace(/\+/g,""))="A + B" (6认同)
  • @Christoph这对我来说都很合理.特别是,我同意他的观点,`encodeURI`似乎只在一个相当模糊的边缘情况下才有用,而且确实不需要存在.我和他有一些不同意见,但我没有看到任何虚假或愚蠢的东西.你认为究竟是什么废话? (2认同)
  • encodeURIComponent('A + B').replace(/\%20/g, '+') + '\n' + decodeURIComponent("A+%2B+B".replace(/\+/g, '%20' )); (2认同)

Kir*_*ati 39

encodeURIComponent没有编码-_.!~*'(),导致在xml字符串中将数据发布到php时出现问题.

例如:
<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");
}
Run Code Online (Sandbox Code Playgroud)

对于解码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 "";
}
Run Code Online (Sandbox Code Playgroud)

  • 它也没有#(磅/散列/数字)符号,即%23. (5认同)
  • @xr280xr 你什么意思?_encodeURIComponent_ 确实将 # 编码为 %23 (也许 2014 年没有?) (3认同)

Dan*_*ian 38

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

  • 你应该使用ecnodeURIComponent(url) (15认同)
  • 这三个功能都有其问题。最好创建自己的函数来完成任务。 (2认同)

30t*_*thh 17

小型比较表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
Run Code Online (Sandbox Code Playgroud)


Jer*_*eph 12

我建议不要使用其中一种方法.写出你自己的功能,做正确的事.

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);
}
Run Code Online (Sandbox Code Playgroud)

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


Pse*_*ist 10

还要记住它们都编码不同的字符集,并选择适当的字符集.encodeURI()编码的字符比encodeURIComponent()编码的字符数少,它比escape()编码的字符数更少(也与dannyp的点不同).


小智 7

出于编码的目的,javascript已经给出了三个内置函数 -

  1. escape() - 不编码@*/+ 在ECMA 3之后不推荐使用此方法,因此应避免使用此方法.

  2. encodeURI() - 不编码~!@#$&*()=:/,;?+' 它假定URI是一个完整的URI,因此不编码URI中具有特殊含义的保留字符.当意图转换完整的URL而不是某些特殊的URL段时,使用此方法.示例 - encodeURI('http://stackoverflow.com'); 将给出 - http://stackoverflow.com

  3. encodeURIComponent() - 不编码 - _ . ! ~ * ' ( ) 此函数通过将某些字符的每个实例替换为表示字符的UTF-8编码的一个,两个,三个或四个转义序列来编码统一资源标识符(URI)组件.此方法应用于转换URL的组件.例如,需要附加一些用户输入示例 - encodeURI('http://stackoverflow.com'); 将给出 - http%3A%2F%2Fstackoverflow.com

所有这些编码都以UTF 8执行,即字符将以UTF-8格式转换.

encodeURIComponent与encodeURI的不同之处在于它编码保留字符和encodeURI的数字符号#


aki*_*uri 6

受到约翰桌子的启发,我决定扩展桌子。我想看看哪些 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);
Run Code Online (Sandbox Code Playgroud)

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


作为补充,我为urlencode()vs添加了另一个表rawurlencode()。唯一的区别似乎是空格字符的编码。

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>
Run Code Online (Sandbox Code Playgroud)


Hol*_*ger 6

只要尝试一下encodeURI(),你encodeURIComponent()自己...

console.log(encodeURIComponent('@#$%^&*'));
Run Code Online (Sandbox Code Playgroud)

输入:@#$%^&*。输出:%40%23%24%25%5E%26*。那么,等等,发生了什么*?为什么这个没有转换?如果您尝试这样做,它肯定会引起问题linux command "$string"。TLDR:您实际上想要fixedEncodeURIComponent()fixedEncodeURI()。很长的故事...

什么时候使用encodeURI() 绝不。 encodeURI()未能遵守有关括号编码的 RFC3986。使用,如MDNencodeURI() 文档fixedEncodeURI()中的定义和进一步解释...

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

什么时候使用encodeURIComponent() 绝不。 encodeURIComponent()未能遵守 RFC3986 关于编码的规定:!'()*。使用,如MDNencodeURIComponent() 文档fixedEncodeURIComponent()中的定义和进一步解释...

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

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