JavaScript對(duì)URL進(jìn)行編碼和解碼的三種方式
前言
我們?cè)陧?xiàng)目開(kāi)發(fā)中用url進(jìn)行參數(shù)傳遞時(shí),經(jīng)常會(huì)傳遞一些中文名的參數(shù)或URL地址,在后臺(tái)處理時(shí)會(huì)發(fā)生轉(zhuǎn)換錯(cuò)誤。本文主要針對(duì)URI編解碼的相關(guān)問(wèn)題做了介紹,對(duì)url為什么需要編碼,編碼有哪幾種方式,并對(duì)比分析了Javascript中和編解碼相關(guān)的幾對(duì)函數(shù)escape / unescape,encodeURI / decodeURI和encodeURIComponent / decodeURIComponent。下面我們一起來(lái)看看吧。
一、為什么要編碼
對(duì)于Url來(lái)說(shuō),之所以要進(jìn)行編碼,是因?yàn)閁rl中有些字符會(huì)引起歧義。比如以下幾種場(chǎng)景:
1.場(chǎng)景一
路徑中包含有中文。然而Url中不能包含任何非ASCII字符,如果客戶端瀏覽器和服務(wù)端瀏覽器支持的字符集不同的情況下,中文可能會(huì)造成問(wèn)題。
https://code-nav.top/download/3?type=視頻教程
2.場(chǎng)景二
Url參數(shù)字符串中使用key=value鍵值對(duì)這樣的形式來(lái)傳參,鍵值對(duì)之間以&符號(hào)分隔,如/s?q=abc&ie=utf-8。如果你的value字符串中包含了=或者&,那么勢(shì)必會(huì)造成接收Url的服務(wù)器解析錯(cuò)誤,因此必須將引起歧義的&和=符號(hào)進(jìn)行轉(zhuǎn)義,也就是對(duì)其進(jìn)行編碼。
根據(jù)RFC標(biāo)準(zhǔn),有些符號(hào)在URI中是不能直接傳遞的,要按照規(guī)定格式進(jìn)行編碼,下面我們看看哪些字符需要編碼傳遞。
二、需要編碼的字符
RFC3986文檔規(guī)定,Url中只允許包含英文字母(a-zA-Z)、數(shù)字(0-9)、-_.~4個(gè)特殊字符以及所有保留字符。因此對(duì)于Url而言,只有普通英文字符和數(shù)字,特殊字符$-_.+!*'()還有保留字符,才能出現(xiàn)在未經(jīng)編碼的Url之中。其他字符均需要經(jīng)過(guò)編碼之后才能出現(xiàn)在Url中。
不安全的字符
| 字符 | 描述 |
| 空格 | Url在傳輸?shù)倪^(guò)程,有可能引入無(wú)關(guān)緊要的空格,或者去掉一些有意義的空格 |
| 引號(hào)以及<> | 引號(hào)和尖括號(hào)通常用于在普通文本中起到分隔Url的作用 |
| # | 通常用于表示書簽或者錨點(diǎn) |
| % | 百分號(hào)本身用作對(duì)不安全字符進(jìn)行編碼時(shí)使用的特殊字符,因此本身需要編碼 |
| {}|^[]`~ | 一些網(wǎng)關(guān)或者傳輸代理會(huì)篡改這些字符 |
對(duì)于上面提到的這些字符,如果不經(jīng)過(guò)編碼,那么它們有可能會(huì)造成Url語(yǔ)義的不同。
三、編碼的三種方式
第一種:escape和 unescape
escape()不能直接用于URL編碼,它的真正作用是返回一個(gè)字符的Unicode編碼值。規(guī)則如下:
| 方法 | 描述 | 返回值 |
| escape() | 使用轉(zhuǎn)義序列替換某些字符來(lái)對(duì)字符串進(jìn)行編碼,除了ASCII字母、數(shù)字、標(biāo)點(diǎn)符號(hào)"@ * _ + - . /"以外 | 返回Unicode編碼字符串 |
| unescape(String) | 對(duì)使用 escape() 編碼的字符串進(jìn)行解碼 |
除了ASCII字母、數(shù)字、標(biāo)點(diǎn)符號(hào)"@ * _ + - . /"以外,對(duì)其他所有字符進(jìn)行編碼。在u0000到u00ff之間的符號(hào)被轉(zhuǎn)成%xx的形式,其余符號(hào)被轉(zhuǎn)成%uxxxx的形式。對(duì)應(yīng)的解碼函數(shù)是unescape()。
編碼:
"https://code-nav.top/download/3?type=" + escape('視頻教程')
解碼:
"https://code-nav.top/download/3?type=" + unescape('%u89C6%u9891%u6559%u7A0B')
注意點(diǎn):
1.首先,無(wú)論網(wǎng)頁(yè)的原始編碼是什么,一旦被Javascript編碼,就都變?yōu)閡nicode字符。也就是說(shuō),Javascipt函數(shù)的輸入和輸出,默認(rèn)都是Unicode字符。這一點(diǎn)對(duì)下面兩個(gè)函數(shù)也適用。
2.其次,escape()不對(duì) "+" 編碼。但是我們知道,網(wǎng)頁(yè)在提交表單的時(shí)候,如果有空格,則會(huì)被轉(zhuǎn)化為+字符。服務(wù)器處理數(shù)據(jù)的時(shí)候,會(huì)把+號(hào)處理成空格。所以,使用的時(shí)候要小心。
第二種:encodeURI 和 decodeURI
encodeURI()是Javascript中真正用來(lái)對(duì)URL編碼的函數(shù)。規(guī)則如下:
| 方法 | 描述 | 返回值 |
| encodeURI(String) | 通過(guò)轉(zhuǎn)義某些字符對(duì) URI 進(jìn)行編碼,除了常見(jiàn)的符號(hào)以外(ASCII 字符),對(duì)其他一些在網(wǎng)址中有特殊含義的符號(hào)"; / ? : @ & = + $ , #",也不進(jìn)行編碼 | 輸出utf-8形式字符串 |
| decodeURI(String) | 對(duì)使用 encodeURI() 方法編碼的字符串進(jìn)行解碼 |
它用于對(duì)URL的組成部分進(jìn)行個(gè)別編碼,除了常見(jiàn)的符號(hào)以外,對(duì)其他一些在網(wǎng)址中有特殊含義的符號(hào)"; / ? : @ & = + $ , #",也不進(jìn)行編碼。編碼后,它輸出符號(hào)的utf-8形式,并且在每個(gè)字節(jié)前加上%,,然后用十六進(jìn)制的轉(zhuǎn)義序列(形式為%xx)對(duì)生成的 1 字節(jié)、2 字節(jié)或 4 字節(jié)的字符進(jìn)行編碼。
它對(duì)應(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ū)別是,它用于對(duì)整個(gè)URL進(jìn)行編碼。"; / ? : @ & = + $ , #",這些在encodeURI()中不被編碼的符號(hào),在encodeURIComponent()中統(tǒng)統(tǒng)會(huì)被編碼。
規(guī)則如下:
| 方法 | 描述 | 返回值 |
| encodeURIComponent(String) | 通過(guò)某些轉(zhuǎn)義字符對(duì) URI 進(jìn)行編碼,會(huì)編譯所有(包含特殊字符),ASCII 字符不編碼,可以將參數(shù)中的中文、特殊字符進(jìn)行轉(zhuǎn)義 | 輸出utf-8形式字符串 |
| deencodeURIComponent(String) | 對(duì)使用 encodeURIComponent() 方法編碼的字符串進(jìn)行解碼 |
它對(duì)應(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ù)包含特殊字符可能會(huì)造成間斷。
三、總結(jié)
escape 官方已不推薦使用了,基本淘汰了,如果想對(duì)URL編碼,最好不要使用此方法,encodeURI和encodeURIComponent比較常用。
后面兩個(gè)函數(shù)區(qū)別:
前者假定它的參數(shù)是 URI 的一部分(比如協(xié)議、主機(jī)名、路徑或查詢字符串)。因此 encodeURIComponent() 函數(shù)將轉(zhuǎn)義用于分隔 URI 各個(gè)部分的標(biāo)點(diǎn)符號(hào)。
以上就是JavaScript對(duì)URL進(jìn)行編碼和解碼的三種方式的詳細(xì)內(nèi)容,更多關(guān)于JS URL編碼解碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript對(duì)象_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了JavaScript對(duì)象的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
三步實(shí)現(xiàn)ionic3點(diǎn)擊退出app程序
這篇文章主要為大家詳細(xì)介紹了三步實(shí)現(xiàn)ionic3點(diǎn)擊退出app程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
JavaScript獲取頁(yè)面中超鏈接數(shù)量的方法
這篇文章主要介紹了JavaScript獲取頁(yè)面中超鏈接數(shù)量的方法,涉及JavaScript針對(duì)頁(yè)面元素獲取及運(yùn)算的相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
CSS+Js遮罩效果的TAB及焦點(diǎn)圖片切換(推薦)
CSS+Js圖片切換技術(shù),類似的已有不少了,這一個(gè)使用了遮罩過(guò)渡的效果,同樣應(yīng)用到了TAB選項(xiàng)卡上,本頁(yè)面僅是為了演示,大家用時(shí)候把它拆分開(kāi)來(lái),這個(gè)效果也對(duì)學(xué)習(xí)圖片效果制作很有幫助。2009-11-11
JavaScript?Canvas實(shí)現(xiàn)圖片局部放大鏡效果
這篇文章主要為大家詳細(xì)介紹了如何使用JavaScript?Canvas實(shí)現(xiàn)圖片局部放大鏡效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
前端強(qiáng)大的圖片預(yù)覽組件Viewer.js使用方法
這篇文章主要給大家介紹了關(guān)于前端強(qiáng)大的圖片預(yù)覽組件Viewer.js使用方法的相關(guān)資料,Viewer.js是一款強(qiáng)大的圖片查看器,雖然簡(jiǎn)單且易上手,但是卻并不影響其在圖片查看方面的強(qiáng)大功能,同時(shí)這款優(yōu)秀的插件配置操作起來(lái)也非常的方便,需要的朋友可以參考下2024-01-01

