簡體   English   中英

我應該使用 encodeURI 還是 encodeURIComponent 來編碼 URL?

[英]Should I use encodeURI or encodeURIComponent for encoding URLs?

應該使用這兩種方法中的哪一種來編碼 URL?

這取決於您實際想要做什么。

encodeURI 假設輸入是一個完整的 URI,其中可能包含一些需要編碼的字符。

encodeURIComponent 將對具有特殊含義的所有內容進行編碼,因此您可以將其用於 URI 的組件,例如

var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);

如果您要對字符串進行編碼以放入 URL 組件(查詢字符串參數),則應調用encodeURIComponent

如果要對現有 URL 進行編碼,請調用encodeURI

xkr.us有一個很好的討論,有例子。 引用他們的總結:

escape() 方法不對 + 字符進行編碼,該字符在服務器端被解釋為空格,以及由字段中帶有空格的表單生成。 由於此缺點以及此函數無法正確處理非 ASCII 字符的事實,您應盡可能避免使用 escape()。 最好的選擇通常是 encodeURIComponent()。

escape() 不會編碼:@*/+

使用 encodeURI() 方法比 escape() 方法更專業,因為它為 URI 編碼,而不是作為 URL 一部分的查詢字符串。 當您需要對字符串進行編碼以用於任何使用 URI 並需要某些字符保持未編碼狀態的資源時,請使用此方法。 請注意,此方法不對 ' 字符進行編碼,因為它是 URI 中的有效字符。

encodeURI() 不會編碼:~!@#$&*()=:/,;?+'

最后,在對 URI 的單個組件進行編碼時,應在大多數情況下使用 encodeURIComponent() 方法。 此方法將對某些通常被識別為 URI 的特殊字符的字符進行編碼,以便可以包含許多組件。 請注意,此方法不對 ' 字符進行編碼,因為它是 URI 中的有效字符。

encodeURIComponent() 不會編碼:~!*()'

這是一個總結。

  1. escape() 不會對 @ * _ + - 進行編碼。 /

    不要使用它。

  2. encodeURI() 不會對 AZ az 0-9 進行編碼; , / ? :@ & = + $ - _ 。 ~ * ' ( ) #

    當您的輸入是完整的 URL 時使用它,例如“ https://searchexample.com/search?q=wiki

  3. encodeURIComponent() 不會對 AZ az 0-9 - _ 進行編碼。 ~ * ' ( ) 當您的輸入是完整 URL 的一部分時使用它,例如const queryStr = encodeURIComponent(someString)

encodeURIencodeURIComponent用於不同的目的。
一些區別是

  1. encodeURI用於編碼完整的 URL,encodeURIComponent用於編碼 URI 組件,例如查詢字符串。

  2. 11 個字符不是由 encodeURI 編碼的,而是由 encodeURIComponent 編碼的。 列表:

特點 編碼URI 編碼URI組件
# # %23
$ $ %24
& & %26
+ + %2B
, , %2C
/ / %2F
%3A
; ; %3B
= = %3D
? ? %3F
@ @ %40

筆記:
encodeURIComponent不編碼 -_.!~*'()。 如果要對這些字符進行編碼,則必須將它們替換為相應的 UTF-8 字符序列

如果您想了解有關 encodeURI 和 encodeURIComponent 的更多信息,請查看參考鏈接。 參考鏈接

encodeURIComponent() :假定其參數是 URI 的一部分(例如協議、主機名、路徑或查詢字符串)。 因此,它會轉義用於分隔 URI 部分的標點字符。

encodeURI(): 用於對現有 url 進行編碼

encodeURIencodeURIComponent區別:

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 + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

以上所有字符都轉換為百分比十六進制代碼。 空格到%20 ,百分比到%25等等。下面的字符通過不變。

以下是函數不會轉換的字符:

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

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

作為一般規則,使用encodeURIComponent 不要害怕長名稱,認為它的用途更具體,對我來說這是更常用的方法。 也不要被吸引使用 encodeURI,因為您測試了它並且它似乎正確編碼,這可能不是您打算使用的,即使您在名字字段中使用“Fred”的簡單測試有效,您也會發現稍后當您使用更高級的文本(例如添加與號或主題標簽)時,它將失敗。 您可以查看其他答案以了解原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM