这两种方法中应该使用哪一种来编码url ?


当前回答

其他答案描述了目的。下面是每个函数实际转换的字符:

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

以上所有字符都转换为百分制16进制代码。空格到%20,百分比到%25,等等。下面的字符没有改变。

以下是函数不会转换的字符:

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )

其他回答

着他。我们有一个很好的讨论,有例子。引用他们的总结:

The escape() method does not encode the + character which is interpreted as a space on the server side as well as generated by forms with spaces in their fields. Due to this shortcoming and the fact that this function fails to handle non-ASCII characters correctly, you should avoid use of escape() whenever possible. The best alternative is usually encodeURIComponent(). escape() will not encode: @*/+ Use of the encodeURI() method is a bit more specialized than escape() in that it encodes for URIs as opposed to the querystring, which is part of a URL. Use this method when you need to encode a string to be used for any resource that uses URIs and needs certain characters to remain un-encoded. Note that this method does not encode the ' character, as it is a valid character within URIs. encodeURI() will not encode: ~!@#$&*()=:/,;?+' Lastly, the encodeURIComponent() method should be used in most cases when encoding a single component of a URI. This method will encode certain chars that would normally be recognized as special chars for URIs so that many components may be included. Note that this method does not encode the ' character, as it is a valid character within URIs. encodeURIComponent() will not encode: ~!*()'

如果要对字符串进行编码以放入URL组件(querystring参数),则应该调用encodeURIComponent。

如果您正在对一个现有URL进行编码,请调用encodeURI。

encodeURI和encodeURIComponent的区别:

encodeURIComponent(value)主要用于编码queryString参数值,它对value中每个适用的字符进行编码。encodeURI忽略协议前缀(http://)和域名)。


在非常非常罕见的情况下,当你想实现手动编码来编码额外的字符时(尽管在典型情况下不需要编码),例如:!*,则 你可以用:

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

(源)

其他答案描述了目的。下面是每个函数实际转换的字符:

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

以上所有字符都转换为百分制16进制代码。空格到%20,百分比到%25,等等。下面的字符没有改变。

以下是函数不会转换的字符:

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )

As a general rule use encodeURIComponent. Don't be scared of the long name thinking it's more specific in it's use, to me it's the more commonly used method. Also don't be suckered into using encodeURI because you tested it and it appears to be encoding properly, it's probably not what you meant to use and even though your simple test using "Fred" in a first name field worked, you'll find later when you use more advanced text like adding an ampersand or a hashtag it will fail. You can look at the other answers for the reasons why this is.