常用編碼
- URL 編碼
- HTML 編碼
- JS 編碼
URL編碼
一般來說饭庞,URL只能使用英文字母(a-zA-Z
)、數(shù)字(0-9
)食拜、-_.~
4個特殊字符以及所有(;,/?:@&=+$#
)保留字符萄涯。
意味著如果使用了一些其他文字和特殊字符陈肛,則需要通過編碼的方式來進行表示,如:
// 使用了漢字
var url1 = 'http://www.帥.com';
另外我們知道在 URL 中傳參是通過鍵值對形式進行的楞黄,格式上是以池凄?
、&
和 =
為特征標(biāo)識進行解析鬼廓,如果在鍵或者值的內(nèi)容中包含一些特殊符號肿仑,就會造成解析錯誤,如下所示:
// 鍵為漢字
var url2 = 'http://www.a.com?我=1';
// 值的內(nèi)容為特殊符號
var url3 = 'http://a.com?key=?&';
對于上面的情況如果我們要正常解析碎税,則需要進行編碼尤慰,需要用不會造成歧義的符號代替有歧義的符號。
我們可以通過使用系統(tǒng)原生實現(xiàn)的 API 來對字符進行 URL 編碼如:
encodeURI
encodeURI 是用來編碼 URI 的雷蹂,最常見的就是編碼一個 URL伟端。encodeURI 會將需要編碼的字符轉(zhuǎn)換為 UTF-8
的格式。對于保留字符(;,/?:@&=+$#
)萎河,以及非轉(zhuǎn)義字符(字母數(shù)字以及 -_.!~*'()
)不會進行轉(zhuǎn)義荔泳。
例如之前 URL 中包含中文,我們可以使用 encodeURI:
encodeURI('http://www.帥.com'); // http://www.%E5%B8%85.com
encodeURI('http://www.a.com?我=1');// "http://www.a.com?%E6%88%91=1"
在這里虐杯,%E5%B8%85
就是 帥
的 URL 編碼玛歌,%E6%88%91
即為 我
的 URL 編碼。然后由于 encodeURI 不轉(zhuǎn)義&
擎椰、?
和=
支子。所以對于 URL 參數(shù)的值是無法轉(zhuǎn)義的,如下面的例子:
// 值的內(nèi)容為特殊符號
encodeURI('http://a.com?key=?&'); // "http://a.com?key=?&"
此時我們就需要使用 encodeURIComponent 來解決达舒。
encodeURIComponent
顧名思義值朋,encodeURIComponent 是用來編碼 URI 參數(shù)的叹侄。它會跳過非轉(zhuǎn)義字符(字母數(shù)字以及-_.!~*'()
)。但會轉(zhuǎn)義 URL的 保留字符(;,/?:@&=+$#
)昨登。通常來說我們會 encodeURI 結(jié)合 encodeURIComponent 來使用趾代,如下所示:
// "http://a.com?a=%3F%26"
encodeURI('http://a.com') + '?a=' + encodeURIComponent('?&');
其中 %3F
和 %26
分別為 ?
和 &
的 URL 編碼。需注意的是由于 encodeURIComponent 會編碼所有的 URL 保留字丰辣,所以不適合編碼 URL撒强,例如:
// "http%3A%2F%2Fa.com%3Fkey%3D%3F%26"
encodeURIComponent('http://a.com?key=?&');
上面的 http%3A%2F%2Fa.com%3Fkey%3D%3F%26
在地址欄會被解析為一個普通的字符串而不是 URL。
URL 解碼
有了 URL 編碼笙什,相應(yīng)的會有解碼機制飘哨。比如上面對應(yīng)的 3個 encode 的API對應(yīng)的解碼 API 如下:
HTML 編碼
在 HTML 中,某些字符是預(yù)留的琐凭,比如不能使用小于號(<
)和大于號(>
)芽隆,這是因為瀏覽器會誤認(rèn)為它們是標(biāo)簽。如果希望正確地顯示預(yù)留字符统屈,我們必須在 HTML 源代碼中使用字符實體(character entities)胚吁。當(dāng)然還另一個重要原因,有些字符在 ASCII 字符集中沒有定義鸿吆,因此需要使用字符實體來表示囤采,比如中文。
HTML 編碼分為:
- HTML 十六進制編碼
&#xH;
- HTML 十進制編碼
&#D;
- HTML 實體編碼
<
等
在 HTML 進制編碼中其中的數(shù)字則是對應(yīng)字符的 unicode 字符編碼惩淳。
比如單引號的 unicode 字符編碼是27蕉毯,則單引號可以被編碼為'
HTML 實體編碼
通常來說,在業(yè)務(wù)中我們用到更多的是 HTML 的實體編碼思犁。常用的 HTML 實體編碼函數(shù)如下所示:
/**
* 轉(zhuǎn)義 HTML 特殊字符
* @param {String} str
*/
function htmlEncode(str) {
return String(str)
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}
更完整的轉(zhuǎn)義列表見這里代虾。
Javascript 轉(zhuǎn)義
JavaScript 中有些字符有特殊用途,如果字符串中想使用這些字符原來的含義激蹲,需要使用反斜杠對這些特殊符號進行轉(zhuǎn)義棉磨。我們稱之為 Javascript編碼。一般有以下幾類:
- 三個八進制數(shù)字学辱,如果不夠個數(shù)乘瓤,前面補0,例如 “e” 編碼為“\145”
- 兩個十六進制數(shù)字策泣,如果不夠個數(shù)衙傀,前面補0,例如 “e” 編碼為“\x65”
- 四個十六進制數(shù)字萨咕,如果不夠個數(shù)统抬,前面補0,例如 “e” 編碼為“\u0065”
- 對于一些控制字符,使用特殊的C類型的轉(zhuǎn)義風(fēng)格(例如\n和\r)
如下面所示聪建,雙引號用于標(biāo)注字符串钙畔,然而在字符串中帶了雙引號,就會發(fā)生歧義:
var str = "Hello"";
于是我們需要對字符串內(nèi)的雙引號進行轉(zhuǎn)義金麸,也就是加上反斜杠擎析,告訴腳本引擎要區(qū)分對待:
var str = "Hello\"";