JS 中對URL傳參包含特殊字符的處理

JS 中對URL傳參包含特殊字符的處理

辛勤工做的一週又悄麼聲的過去,感受一週立刻過去了,應該乾點啥,具體乾點啥,嗯~~不敢問,不敢說,不敢想,啊哈,靈機一動,仍是小結一篇文章表示曾經來過(這篇文章就在吃着川川的煎餅中英勇蛋生了!!!)。php

本文由「十有八九」投稿,若有錯誤,歡迎指正。html

聲明文章參考一些博客,文章來源在文章末尾指出,若是遺漏,歡迎指出。python

文章總結背景

在項目中不少時候會遇到URL中帶有特殊字符的傳參問題,後端接收到錯誤的參數信息,致使功能失敗。後端

特殊字符的含義(十六進制):瀏覽器

符號 解釋 轉義
# 用來標誌特定的文檔位置 %23
% 對特殊字符進行編碼 %25
& 分隔不一樣的變量值對 %26
+ 在變量值中表示空格 %2B
/ 表示目錄路徑 %2F
\ 表示目錄路徑 %5C
= 用來鏈接鍵和值 %3D
? 表示查詢字符串的開始 %3F
空格 空格 %20
. 句號 %2E
: 冒號 %3A

針對上面提出的問題,普通的解決方法---正則替換解決,先來秀一波:bash

replace()方法替換匹配到的第一個字符串:str.replace('abc', 'Hello') replace()方法替換匹配到的全部字符串:str.replace(/abc/g, 'hello')服務器

js中替換字符變量以下:函數

str=str.replace(/\%/g,"%25"); 
str=str.replace(/\#/g,"%23"); 
str=str.replace(/\&/g,"%26"); 
...
複製代碼

不但累成🐶,還沒替換完,速度超級慢,還有遺漏的沒替換???。。。編碼

同事看到了你的這段代碼轉換,一臉懵逼,腦殼浮現一個詞形容:「What?」,避免被吐槽,趕忙去複習總結了下各方法的區別,但願對讀到這篇文章的你能有所幫助。url

escape(str)方法

escape(str)方法生成新的由十六進制轉義序列替換的字符串。

escape函數是全局對象的屬性。該方法不會對ASCII字母和數字進行編碼,其餘全部的字符都會被轉義序列替換,其中對中文編碼使用Unicode字符集,下面特殊字符除外:@ * _ + - ./

字符的十六進制形式,其代碼單元值爲0xFF或更小,是一個兩位數的轉義序列:%xx。對於具備更大代碼單元的字符,使用四位數格式%u xxxx。

代碼示例以下:

escape('中文&hello@world') // %u4E2D%u6587%26hello@world
escape('abc123');        // abc123
escape('?');            // "%u0107"
複製代碼

\color{#FF8C00}{注:該特性已經從Web標準中刪除,雖然一些瀏覽器目前仍然支持它,但也許會在將來的某個時間中止支持,請儘可能不要使用該特性。}

encodeURI(URI)方法

該encodeURI()函數經過使用1到4個轉義序列來表示每一個字符的UTF-8編碼來對統一資源標識符(URI)編碼,(對於由兩個字符組成的字符,用四個轉義字符編碼)。

假設有一個完整的URI,那麼encodeURI不會編碼那些對URI有特殊意義的字符。encodeURI不會編碼如下特殊字符:**! @ # $& * ( ) = : / ; ? + ' **

encodeURIComponent(URI)方法

把URI字符串採用UTF-8編碼格式轉化成escape格式的字符串。與encodeURI()相比,這個方法將對更多的字符進行編碼,如:反斜槓(‘/’);encodeURIComponent 轉義除了字母、數字、(、)、.、!、~、*、'、-和_以外的全部字符。

注意:若是字符串裏面包含了URI的幾個部分的話,不能用這個方法來進行編碼,不然 / 字符被編碼以後URL將顯示錯誤。

代碼示例以下:

encodeURIComponent("123-_.!~*'()abc")   // "123-_.!~*'()abc"
encodeURIComponent(";/?:@&=+$,#")  // "%3B%2F%3F%3A%40%26%3D%2B%24%2C%23"
encodeURIComponent("abc123")      // "abc123"
encodeURIComponent('中文&ABC/hello')  //"%E4%B8%AD%E6%96%87%26ABC%2Fhello"
複製代碼

encodeURIComponent是被使用最多的,它是將中文等特殊字符轉換成utf-8格式的url編碼。

encodeURI()和encodeURIComponent()的區別

舉個栗子🌰來講明一下:

如今我要使用get方式將一個參數fromUrl,傳遞給服務器:

var  fromUrl="getList?id=1&name=zhangsan"; 
var  getURL="http://www.XXX.cn/test.php?form="+encodeURI(fromUrl);

這裏,若是使用了encodeURI,那麼最終的getURL的值爲: 
"http://www.XXX.cn/test.php?form=getList?id=1&name=zhangsan"

這樣,對參數fromUrl中的字符"&name=zhangsan",將不會做爲字符串參數傳遞到服務器端,而是看成test.php的參數傳遞過去了,由於對"&name=zhangsan"中的字符"&"沒有作編碼。 
因此,在這種應用場景下,就須要使用encodeURIComponent,編碼後的getURL值爲: 
"http://www.XXX.cn/test.php?form=getList%3Fid%3D1%26name%3Dzhangsan"
複製代碼

方法總結

  1. escape()除了ASCII字母、數字和特定的符號外(@ * _ + - ./*),對傳進來的字符串所有進行轉義編碼,所以若是想對URL編碼,最好不要使用此方法。(該特性已經從Web標準中刪除)
  2. encodeURI() 用於編碼整個URI,由於URI中的合法字符都不會被編碼轉換
  3. encodeURIComponent()方法在編碼單個URIComponent(指請求參數)應當是最經常使用的,它能夠將參數中的中文、特殊字符進行轉義,而不會影響整個URL。
  4. encodeURI()和encodeURIComponent()對中文的編碼方式同樣,一箇中文3個十六進制的轉義序列組成,默認編碼字符集爲UTF-8。

參考文章:

JAVASCRIPT中URL 傳遞參數(特殊字符)解決方法及轉碼解碼的介紹

encode()

拓展:

ES5/標準 ECMAScript內置對象

相關文章
相關標籤/搜索