JavaScript對URL進行編碼和解碼的三種方式
前言
我們在項目開發(fā)中用url進行參數(shù)傳遞時,經(jīng)常會傳遞一些中文名的參數(shù)或URL地址,在后臺處理時會發(fā)生轉(zhuǎn)換錯誤。本文主要針對URI編解碼的相關(guān)問題做了介紹,對url為什么需要編碼,編碼有哪幾種方式,并對比分析了Javascript中和編解碼相關(guān)的幾對函數(shù)escape / unescape,encodeURI / decodeURI和encodeURIComponent / decodeURIComponent。下面我們一起來看看吧。
一、為什么要編碼
對于Url來說,之所以要進行編碼,是因為Url中有些字符會引起歧義。比如以下幾種場景:
1.場景一
路徑中包含有中文。然而Url中不能包含任何非ASCII字符,如果客戶端瀏覽器和服務(wù)端瀏覽器支持的字符集不同的情況下,中文可能會造成問題。
https://code-nav.top/download/3?type=視頻教程
2.場景二
Url參數(shù)字符串中使用key=value鍵值對這樣的形式來傳參,鍵值對之間以&符號分隔,如/s?q=abc&ie=utf-8。如果你的value字符串中包含了=或者&,那么勢必會造成接收Url的服務(wù)器解析錯誤,因此必須將引起歧義的&和=符號進行轉(zhuǎn)義,也就是對其進行編碼。
根據(jù)RFC標(biāo)準(zhǔn),有些符號在URI中是不能直接傳遞的,要按照規(guī)定格式進行編碼,下面我們看看哪些字符需要編碼傳遞。
二、需要編碼的字符
RFC3986文檔規(guī)定,Url中只允許包含英文字母(a-zA-Z)、數(shù)字(0-9)、-_.~4個特殊字符以及所有保留字符。因此對于Url而言,只有普通英文字符和數(shù)字,特殊字符$-_.+!*'()還有保留字符,才能出現(xiàn)在未經(jīng)編碼的Url之中。其他字符均需要經(jīng)過編碼之后才能出現(xiàn)在Url中。
不安全的字符
字符 | 描述 |
空格 | Url在傳輸?shù)倪^程,有可能引入無關(guān)緊要的空格,或者去掉一些有意義的空格 |
引號以及<> | 引號和尖括號通常用于在普通文本中起到分隔Url的作用 |
# | 通常用于表示書簽或者錨點 |
% | 百分號本身用作對不安全字符進行編碼時使用的特殊字符,因此本身需要編碼 |
{}|^[]`~ | 一些網(wǎng)關(guān)或者傳輸代理會篡改這些字符 |
對于上面提到的這些字符,如果不經(jīng)過編碼,那么它們有可能會造成Url語義的不同。
三、編碼的三種方式
第一種:escape和 unescape
escape()不能直接用于URL編碼,它的真正作用是返回一個字符的Unicode編碼值。規(guī)則如下:
方法 | 描述 | 返回值 |
escape() | 使用轉(zhuǎn)義序列替換某些字符來對字符串進行編碼,除了ASCII字母、數(shù)字、標(biāo)點符號"@ * _ + - . /"以外 | 返回Unicode編碼字符串 |
unescape(String) | 對使用 escape() 編碼的字符串進行解碼 |
除了ASCII字母、數(shù)字、標(biāo)點符號"@ * _ + - . /"以外,對其他所有字符進行編碼。在u0000到u00ff之間的符號被轉(zhuǎn)成%xx的形式,其余符號被轉(zhuǎn)成%uxxxx的形式。對應(yīng)的解碼函數(shù)是unescape()。
編碼:
"https://code-nav.top/download/3?type=" + escape('視頻教程')
解碼:
"https://code-nav.top/download/3?type=" + unescape('%u89C6%u9891%u6559%u7A0B')
注意點:
1.首先,無論網(wǎng)頁的原始編碼是什么,一旦被Javascript編碼,就都變?yōu)閡nicode字符。也就是說,Javascipt函數(shù)的輸入和輸出,默認都是Unicode字符。這一點對下面兩個函數(shù)也適用。
2.其次,escape()不對 "+" 編碼。但是我們知道,網(wǎng)頁在提交表單的時候,如果有空格,則會被轉(zhuǎn)化為+字符。服務(wù)器處理數(shù)據(jù)的時候,會把+號處理成空格。所以,使用的時候要小心。
第二種:encodeURI 和 decodeURI
encodeURI()是Javascript中真正用來對URL編碼的函數(shù)。規(guī)則如下:
方法 | 描述 | 返回值 |
encodeURI(String) | 通過轉(zhuǎn)義某些字符對 URI 進行編碼,除了常見的符號以外(ASCII 字符),對其他一些在網(wǎng)址中有特殊含義的符號"; / ? : @ & = + $ , #",也不進行編碼 | 輸出utf-8形式字符串 |
decodeURI(String) | 對使用 encodeURI() 方法編碼的字符串進行解碼 |
它用于對URL的組成部分進行個別編碼,除了常見的符號以外,對其他一些在網(wǎng)址中有特殊含義的符號"; / ? : @ & = + $ , #",也不進行編碼。編碼后,它輸出符號的utf-8形式,并且在每個字節(jié)前加上%,,然后用十六進制的轉(zhuǎn)義序列(形式為%xx)對生成的 1 字節(jié)、2 字節(jié)或 4 字節(jié)的字符進行編碼。
它對應(yīng)的解碼函數(shù)是decodeURI()。
編碼:
encodeURI('https://code-nav.top/download/3?type=視頻教程')
解碼:
decodeURI('https://code-nav.top/download/3?type=%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B')
第三種: encodeURIComponent 和 decodeURIComponent
與encodeURI()的區(qū)別是,它用于對整個URL進行編碼。"; / ? : @ & = + $ , #",這些在encodeURI()中不被編碼的符號,在encodeURIComponent()中統(tǒng)統(tǒng)會被編碼。
規(guī)則如下:
方法 | 描述 | 返回值 |
encodeURIComponent(String) | 通過某些轉(zhuǎn)義字符對 URI 進行編碼,會編譯所有(包含特殊字符),ASCII 字符不編碼,可以將參數(shù)中的中文、特殊字符進行轉(zhuǎn)義 | 輸出utf-8形式字符串 |
deencodeURIComponent(String) | 對使用 encodeURIComponent() 方法編碼的字符串進行解碼 |
它對應(yīng)的解碼函數(shù)是decodeURIComponent()。
編碼:
encodeURIComponent('https://code-nav.top/download/3?type=視頻教程')
解碼:
decodeURIComponent('https%3A%2F%2Fcode-nav.top%2Fdownload%2F3%3Ftype%3D%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B')
注意:參數(shù)包含特殊字符可能會造成間斷。
三、總結(jié)
escape 官方已不推薦使用了,基本淘汰了,如果想對URL編碼,最好不要使用此方法,encodeURI和encodeURIComponent比較常用。
后面兩個函數(shù)區(qū)別:
前者假定它的參數(shù)是 URI 的一部分(比如協(xié)議、主機名、路徑或查詢字符串)。因此 encodeURIComponent() 函數(shù)將轉(zhuǎn)義用于分隔 URI 各個部分的標(biāo)點符號。
以上就是JavaScript對URL進行編碼和解碼的三種方式的詳細內(nèi)容,更多關(guān)于JS URL編碼解碼的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript對象_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細介紹了JavaScript對象的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06JavaScript?Canvas實現(xiàn)圖片局部放大鏡效果
這篇文章主要為大家詳細介紹了如何使用JavaScript?Canvas實現(xiàn)圖片局部放大鏡效果,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03