URL編碼與解碼


 

在項目中碰到了ajax傳來的參數,后台接收值亂碼(如下圖)的問題 在此記錄一下

前台:

QQ截圖20150824170202

后台:

QQ截圖20150824170639


解決問題

  • 為什么需要編碼
  • 怎樣編碼
  • 實際出現的問題解決方法

1.為什么需要編碼?

URL 只能使用 ASCII 字符集來通過因特網進行發送。 也就是說URL只能使用英文字母、阿拉伯數字和某些標點符號,不能使用其他文字和符號  
 

這意味着 如果URL中有漢字,就必須編碼后使用。

但是麻煩的是 標准的國際組織並沒有規定具體的編碼方法,而是交給應用程序(瀏覽器)自己決定。

這導致"URL編碼"成為了一個混亂的領域。 

 

 

1.1 瀏覽器對於中文的編碼

Chrome瀏覽器和火狐的瀏覽器是一樣的如下圖,"文"和"章"的utf-8編碼分別是"E6 96 87"和"E7 AB A0" ,

下圖所示的"%e6%96%87%e7%ab%a0"就是按照順序,在每個字節前加上%而得到的

chrome

 


 

Edge瀏覽器和IE瀏覽器是一樣的,如下圖 這個的編碼方式我沒看出來,希望高手指點

IE

 

1.2 需要編碼的原因還有幾點:

 

你有沒有想過,Ukey=value這種傳參方式式中, Value中包含 ?或者 = 怎么辦呢

你有沒有想過,不同的操作系統、瀏覽器、不同的網頁字符集(charset)會對你的傳值造成影響呢

如果你都考慮過,毫無疑問你早就知道需要編碼的原因了


2.怎樣編碼?

Url編碼通常也被稱為百分號編碼(percent-encoding),是因為它的編碼方式非常簡單,

使用%百分號加上兩位的字符——0123456789ABCDEF——代表一個字節的十六進制形式

對於ASCII字符,字母a 在ASCII碼中對應的字節是0x61,那么Url編碼之后得到的就是%61,

字母abc, url編碼后得到的就是%61%62%63

對於非ASCII字符,RFC文檔建議使用utf-8對其進行編碼得到相應的字節,然后對每個字節執行百分號編碼。

如"中文"使用UTF-8字符集得到的字節為0xE4 0xB8 0xAD 0xE6 0x96 0x87,經過Url編碼之后得到"%E4%B8%AD%E6%96%87"。

 
使用Javascript先對URL編碼,然后再向服務器提交,不要給瀏覽器插手的機會 這樣就能保證客戶端只用一種編碼方法向服務器發出請求  

3.實際出現的問題解決方法

首先說一下js的三種編碼函數,escape、encodeURI和encodeURIComponent

 

3.1.escape函數:

js中編碼出生最早的一個,不提倡使用,原因是它不符合我上邊(【怎樣】)說的url編碼原則

真正作用是:

返回一個字符的Unicode編碼值,為的是方便他們能在所有計算機上可讀

具體規則是:

所有空格、標點以及其他非ASCII字符都用%xx編碼替換; 例如空格返回的是%20 字符值大於255的字符以%uxxxx格式儲存

所以以后如果看到%u的編碼,那就是escape函數

看下邊這個列子 你就很清楚的知道它的具體轉換規則了

image

 

escape 文章


 

項目中使用:

前台:

function HandlerAddress() {
            $.ajax({
                type: "get",
                //用的是js的escape方法
                url: "handler/Handler.ashx?address=" + escape("朝陽區大屯路東"),
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                //todo成功方法
                },
                error: function (XMLhttpRequest, textStatus, errorThrown) {
                //todo失敗方法
                }
            })

后台:

escape 時間列后台

QueryString 這個函數會自動解碼,所以不需要寫什么解碼的語句。

還有一點需要注意的是:

escape()不對"+"編碼。但是我們知道,網頁在提交表單的時候,如果有空格,則會被轉化為+字符。服務器處理數據的時候,會把+號處理成空格。所以,使用的時候要小心。

 

3.2.encodeURI函數

這個函數才是javascript中真正用來對URL編碼的函數

規則就是我上面第二部分所說的,采用utf-8編碼。

前台:

QQ截圖20150824170202

后台:

QQ截圖20150824170639

 

用這個方法會存在亂碼的問題,看到很多人問這問題的時候,回答者都是讓采用escape這種方法,難道這樣問題就解決了嗎?

如果我想用Jquery的serialize()方法來獲取表單值並且序列化(標准URL編碼)傳到后台就不方便用escape啦


解決亂碼問題:

出現亂碼的原因是我的web config文件里有這樣的配置:

<globalization requestEncoding="gb2312" responseEncoding="gb2312" />

 

解決方案1:去掉這個設置或者改成utf-8的(這個方案的利害不用說,尤其是在項目已經快完成的時候)


解決方案2:利用ajax的post方法,或者用Get方法,但必須作為方法的Data參數,這樣在后台接收到的數據不會被編碼

前台:

$.ajax({
                type: "get",
                //用的是js的encodeURI方法
                url: "handler/Handler.ashx",
                //作為Data參數
                data: { address: encodeURI("朝陽區大屯路東") },

                contentType: "application/json; charset=utf-8",
                success: function (data) {
                //todo成功方法
                },
                error: function (XMLhttpRequest, textStatus, errorThrown) {
                //todo失敗方法
                }
            })

后台:需要手動解碼一次

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:獲取已編碼的原始數據,自己進行解碼

通過觀察Request的對象,可以發現context.Request.Url.Query是未解碼的數據,這就太棒了

url.query

代碼:

string address= HttpUtility.ParseQueryString(context.Request.Url.Query, Encoding.UTF8)["address"];

解決方案4(探討):先將QueryString解碼的數據按照他原來的方式進行編碼,然后再用utf8進行解碼,這個方法有點問題,最后一個字符會出現亂碼,還沒找到原因.. 

先編碼在接嗎

在將數據編碼的時候,就不是原來的瀏覽器發送的編碼值了,正確的是最后邊應該是%9C,但現在卻是%3f

3.3.encodeURIComponent函數

與encodeURI()的區別是,它用於對URL的組成部分進行個別編碼,而不用於對整個URL進行編碼。

因此,"; / ? : @ & = + $ , #",這些在encodeURI()中不被編碼的符號,在encodeURIComponent()中統統會被編碼

具體的編碼規則是和encodeURI函數是一樣的,如下,encodeURI不會編碼 ?@,而encodeURIComponent會

比較

 

encodeURIComponent這個函數就和他的名字一樣,是對URI中的一個組件進行編碼,不能用於全部的URI

三種比較

 

 

初次寫文章,如果有錯誤或者表達的不清楚,盡管提出來,吐槽黑我 都可以 反正我臉皮厚吸血蝙蝠

 

 

參考:阮一峰-關於URL編碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM