.Net結(jié)合JS實(shí)現(xiàn)URL編碼與解碼
在項(xiàng)目中碰到了ajax傳來(lái)的參數(shù),后臺(tái)接收值亂碼(如下圖)的問(wèn)題 在此記錄一下
前臺(tái):
后臺(tái):
解決問(wèn)題
- 為什么需要編碼
- 怎樣編碼
- 實(shí)際出現(xiàn)的問(wèn)題解決方法
1.為什么需要編碼?
URL 只能使用 ASCII 字符集來(lái)通過(guò)因特網(wǎng)進(jìn)行發(fā)送。
也就是說(shuō)URL只能使用英文字母、阿拉伯?dāng)?shù)字和某些標(biāo)點(diǎn)符號(hào),不能使用其他文字和符號(hào)
這意味著 如果URL中有漢字,就必須編碼后使用。
但是麻煩的是 標(biāo)準(zhǔn)的國(guó)際組織并沒(méi)有規(guī)定具體的編碼方法,而是交給應(yīng)用程序(瀏覽器)自己決定。
這導(dǎo)致"URL編碼"成為了一個(gè)混亂的領(lǐng)域。
1.1 瀏覽器對(duì)于中文的編碼
Chrome瀏覽器和火狐的瀏覽器是一樣的如下圖,"文"和"章"的utf-8編碼分別是"E6 96 87"和"E7 AB A0" ,
下圖所示的"%e6%96%87%e7%ab%a0"就是按照順序,在每個(gè)字節(jié)前加上%而得到的
Edge瀏覽器和IE瀏覽器是一樣的,如下圖 這個(gè)的編碼方式我沒(méi)看出來(lái),希望高手指點(diǎn)
1.2 需要編碼的原因還有幾點(diǎn)
你有沒(méi)有想過(guò),Ukey=value這種傳參方式式中, Value中包含 ?
或者 =
怎么辦呢
你有沒(méi)有想過(guò),不同的操作系統(tǒng)、瀏覽器、不同的網(wǎng)頁(yè)字符集(charset)會(huì)對(duì)你的傳值造成影響呢
如果你都考慮過(guò),毫無(wú)疑問(wèn)你早就知道需要編碼的原因了
2.怎樣編碼?
Url編碼通常也被稱(chēng)為百分號(hào)編碼(percent-encoding),是因?yàn)樗木幋a方式非常簡(jiǎn)單,
使用%百分號(hào)加上兩位的字符——0123456789ABCDEF——代表一個(gè)字節(jié)的十六進(jìn)制形式
對(duì)于ASCII字符,字母a 在ASCII碼中對(duì)應(yīng)的字節(jié)是0x61,那么Url編碼之后得到的就是%61,
字母abc, url編碼后得到的就是%61%62%63
對(duì)于非ASCII字符,RFC文檔建議使用utf-8對(duì)其進(jìn)行編碼得到相應(yīng)的字節(jié),然后對(duì)每個(gè)字節(jié)執(zhí)行百分號(hào)編碼。
如"中文"使用UTF-8字符集得到的字節(jié)為0xE4 0xB8 0xAD 0xE6 0x96 0x87,經(jīng)過(guò)Url編碼之后得到"%E4%B8%AD%E6%96%87"。
使用Javascript先對(duì)URL編碼,然后再向服務(wù)器提交,不要給瀏覽器插手的機(jī)會(huì)
這樣就能保證客戶(hù)端只用一種編碼方法向服務(wù)器發(fā)出請(qǐng)求
3.實(shí)際出現(xiàn)的問(wèn)題解決方法
首先說(shuō)一下js的三種編碼函數(shù),escape
、encodeURI
和encodeURIComponent
3.1.escape函數(shù):
js中編碼出生最早的一個(gè),不提倡使用,原因是它不符合我上邊(【怎樣】)說(shuō)的url編碼原則
真正作用是:
返回一個(gè)字符的Unicode編碼值,為的是方便他們能在所有計(jì)算機(jī)上可讀
具體規(guī)則是:
所有空格、標(biāo)點(diǎn)以及其他非ASCII字符都用%xx編碼替換; 例如空格返回的是%20 字符值大于255的字符以%uxxxx格式儲(chǔ)存
所以以后如果看到%u的編碼,那就是escape函數(shù)
看下邊這個(gè)列子 你就很清楚的知道它的具體轉(zhuǎn)換規(guī)則了
項(xiàng)目中使用:
前臺(tái):
function HandlerAddress() { $.ajax({ type: "get", //用的是js的escape方法 url: "handler/Handler.ashx?address=" + escape("朝陽(yáng)區(qū)大屯路東"), contentType: "application/json; charset=utf-8", success: function (data) { //todo成功方法 }, error: function (XMLhttpRequest, textStatus, errorThrown) { //todo失敗方法 } }) }
后臺(tái):
QueryString 這個(gè)函數(shù)會(huì)自動(dòng)解碼,所以不需要寫(xiě)什么解碼的語(yǔ)句。
還有一點(diǎn)需要注意的是:
escape()不對(duì)"+"編碼。但是我們知道,網(wǎng)頁(yè)在提交表單的時(shí)候,如果有空格,則會(huì)被轉(zhuǎn)化為+字符。服務(wù)器處理數(shù)據(jù)的時(shí)候,會(huì)把+號(hào)處理成空格。所以,使用的時(shí)候要小心。
3.2.encodeURI函數(shù)
這個(gè)函數(shù)才是javascript中真正用來(lái)對(duì)URL編碼的函數(shù)
規(guī)則就是我上面第二部分所說(shuō)的,采用utf-8編碼。
前臺(tái):
后臺(tái):
用這個(gè)方法會(huì)存在亂碼的問(wèn)題,看到很多人問(wèn)這問(wèn)題的時(shí)候,回答者都是讓采用escape這種方法,難道這樣問(wèn)題就解決了嗎?
如果我想用Jquery的serialize()
方法來(lái)獲取表單值并且序列化(標(biāo)準(zhǔn)URL編碼)傳到后臺(tái)就不方便用escape啦
解決亂碼問(wèn)題:
出現(xiàn)亂碼的原因是我的web.config文件里有這樣的配置:
<globalization requestEncoding="gb2312" responseEncoding="gb2312" />
解決方案1:去掉這個(gè)設(shè)置或者改成utf-8的(這個(gè)方案的利害不用說(shuō),尤其是在項(xiàng)目已經(jīng)快完成的時(shí)候)
解決方案2:利用ajax的post方法,或者用Get方法,但必須作為方法的Data參數(shù),這樣在后臺(tái)接收到的數(shù)據(jù)不會(huì)被編碼
前臺(tái):
$.ajax({ type: "get", //用的是js的encodeURI方法 url: "handler/Handler.ashx", //作為Data參數(shù) data: { address: encodeURI("朝陽(yáng)區(qū)大屯路東") }, contentType: "application/json; charset=utf-8", success: function (data) { //todo成功方法 }, error: function (XMLhttpRequest, textStatus, errorThrown) { //todo失敗方法 } })
后臺(tái):需要手動(dòng)解碼一次
string ad =HttpUtility.UrlDecode(context.Request["address"]);
HttpUtility.UrlDecode
和Server.UrlDecode
不同的是,HttpUtility.UrlDecode
是有重載的,可以指定編碼的方式
例如:
string adsx = HttpUtility.UrlDecode(context.Request.QueryString["address"],System.Text.Encoding.UTF8);
解決方案3:獲取已編碼的原始數(shù)據(jù),自己進(jìn)行解碼
通過(guò)觀察Request的對(duì)象,可以發(fā)現(xiàn)context.Request.Url.Query是未解碼的數(shù)據(jù),這就太棒了
代碼:
string address= HttpUtility.ParseQueryString(context.Request.Url.Query, Encoding.UTF8)["address"];
解決方案4(探討):先將QueryString解碼的數(shù)據(jù)按照他原來(lái)的方式進(jìn)行編碼,然后再用utf8進(jìn)行解碼,這個(gè)方法有點(diǎn)問(wèn)題,最后一個(gè)字符會(huì)出現(xiàn)亂碼,還沒(méi)找到原因..
在將數(shù)據(jù)編碼的時(shí)候,就不是原來(lái)的瀏覽器發(fā)送的編碼值了,正確的是最后邊應(yīng)該是%9C,但現(xiàn)在卻是%3f
3.3.encodeURIComponent函數(shù)
與encodeURI()的區(qū)別是,它用于對(duì)URL的組成部分進(jìn)行個(gè)別編碼,而不用于對(duì)整個(gè)URL進(jìn)行編碼。
因此,"; / ? : @ & = + $ , #",這些在encodeURI()中不被編碼的符號(hào),在encodeURIComponent()中統(tǒng)統(tǒng)會(huì)被編碼
具體的編碼規(guī)則是和encodeURI函數(shù)是一樣的,如下,encodeURI不會(huì)編碼 ? 和 @,而encodeURIComponent會(huì)
encodeURIComponent這個(gè)函數(shù)就和他的名字一樣,是對(duì)URI中的一個(gè)組件進(jìn)行編碼,不能用于全部的URI
到此這篇關(guān)于.Net結(jié)合JS實(shí)現(xiàn)URL編碼與解碼的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ASP.NET編譯執(zhí)行常見(jiàn)錯(cuò)誤及解決方法匯總
ASP.NET編譯執(zhí)行常見(jiàn)錯(cuò)誤及解決方法匯總,開(kāi)發(fā)asp.net的朋友可以參考下。方便以后解決一些錯(cuò)誤。2011-12-12使用ASP.Net?WebAPI構(gòu)建REST服務(wù)
這篇文章介紹了使用ASP.Net?WebAPI構(gòu)建REST服務(wù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06Asp.net mvc 權(quán)限過(guò)濾和單點(diǎn)登錄(禁止重復(fù)登錄)
這篇文章主要介紹了Asp.net mvc 權(quán)限過(guò)濾和單點(diǎn)登錄(禁止重復(fù)登錄)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12Entity Framework Core更新時(shí)間映射
這篇文章介紹了Entity Framework Core更新時(shí)間映射的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03Equals和==的區(qū)別 公共變量和屬性的區(qū)別小結(jié)
Equals 和==的區(qū)別 公共變量和屬性的區(qū)別 總結(jié)一下。2009-11-11簡(jiǎn)單使用BackgroundWorker創(chuàng)建多個(gè)線程的教程
簡(jiǎn)單使用BackgroundWorker創(chuàng)建多個(gè)線程的教程,需要的朋友可以參考一下2013-03-03.Net結(jié)合JS實(shí)現(xiàn)URL編碼與解碼
這篇文章介紹了.Net結(jié)合JS實(shí)現(xiàn)URL編碼與解碼的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03淺談對(duì)Jquery+JSON+WebService的使用小結(jié)
本篇文章介紹了對(duì)Jquery+JSON+WebService的使用小結(jié)。需要的朋友參考下2013-04-04c#生成圖片縮略圖的類(lèi)(2種實(shí)現(xiàn)思路)
4個(gè)重載方法,有直接返回Image對(duì)象的,有生成縮略圖,并且保存到指定目錄的,具體祥看下文2013-05-05