前臺:
后臺:
URL 只能使用 ASCII 字符集來通過因特網進行發送。 也就是說URL只能使用英文字母、阿拉伯數字和某些標點符號,不能使用其他文字和符號
這意味著 如果URL中有漢字,就必須編碼后使用。
但是麻煩的是 標準的國際組織并沒有規定具體的編碼方法,而是交給應用程序(瀏覽器)自己決定。
這導致"URL編碼"成為了一個混亂的領域。
Chrome瀏覽器和火狐的瀏覽器是一樣的如下圖,"文"和"章"的utf-8編碼分別是"E6 96 87"和"E7 AB A0" ,
下圖所示的"%e6%96%87%e7%ab%a0"就是按照順序,在每個字節前加上%而得到的
Edge瀏覽器和IE瀏覽器是一樣的,如下圖 這個的編碼方式我沒看出來,希望高手指點
你有沒有想過,Ukey=value這種傳參方式式中, Value中包含
?
或者=
怎么辦呢你有沒有想過,不同的操作系統、瀏覽器、不同的網頁字符集(charset)會對你的傳值造成影響呢
如果你都考慮過,毫無疑問你早就知道需要編碼的原因了
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編碼,然后再向服務器提交,不要給瀏覽器插手的機會這樣就能保證客戶端只用一種編碼方法向服務器發出請求
js中編碼出生最早的一個,不提倡使用,原因是它不符合我上邊(【怎樣】)說的url編碼原則
真正作用是:
返回一個字符的Unicode編碼值,為的是方便他們能在所有計算機上可讀
具體規則是:
所有空格、標點以及其他非ASCII字符都用%xx編碼替換; 例如空格返回的是%20 字符值大于255的字符以%uxxxx格式儲存
所以以后如果看到%u的編碼,那就是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失敗方法 } })
后臺:
QueryString 這個函數會自動解碼,所以不需要寫什么解碼的語句。
還有一點需要注意的是:
escape()不對"+"編碼。但是我們知道,網頁在提交表單的時候,如果有空格,則會被轉化為+字符。服務器處理數據的時候,會把+號處理成空格。所以,使用的時候要小心。
這個函數才是javascript中真正用來對URL編碼的函數
規則就是我上面第二部分所說的,采用utf-8編碼。
前臺:
后臺:
用這個方法會存在亂碼的問題,看到很多人問這問題的時候,回答者都是讓采用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是未解碼的數據,這就太棒了
代碼:
string address= HttpUtility.ParseQueryString(context.Request.Url.Query, Encoding.UTF8)["address"];
解決方案4(探討):先將QueryString解碼的數據按照他原來的方式進行編碼,然后再用utf8進行解碼,這個方法有點問題,最后一個字符會出現亂碼,還沒找到原因..
在將數據編碼的時候,就不是原來的瀏覽器發送的編碼值了,正確的是最后邊應該是%9C,但現在卻是%3f
與encodeURI()的區別是,它用于對URL的組成部分進行個別編碼,而不用于對整個URL進行編碼。
因此,"; / ? : @ & = + $ , #",這些在encodeURI()中不被編碼的符號,在encodeURIComponent()中統統會被編碼
具體的編碼規則是和encodeURI函數是一樣的,如下,encodeURI不會編碼 ? 和 @,而encodeURIComponent會
encodeURIComponent這個函數就和他的名字一樣,是對URI中的一個組件進行編碼,不能用于全部的URI
初次寫文章,如果有錯誤或者表達的不清楚,盡管提出來,吐槽黑我 都可以 反正我臉皮厚
參考:阮一峰-關于URL編碼