亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ASP.NET亂碼深度剖析

2019-11-17 01:53:57
字體:
來源:轉載
供稿:網友

asp.net亂碼深度剖析

寫在前面

在Web開發中,亂碼應該算一個常客了。今天還好好的一個頁面,第二天過來打開一看,中文字符全變“外星文”了。有時為了解決這樣的問題,需要花上很長的時間去調試,直至抓狂,筆者也曾經歷過這樣的時期。有時雖然是“僥幸”解決了,但對其中的原理卻一知半解。

為了弄清楚這個問題,今天查了大半天的資料、測試。現把這些點滴記錄下來,以激勵自己重視基礎,同時和大家分享一下,望大家不吝批評指正。

預備知識

先介紹一些字符編碼方面的基本知識,如果你對這些已經比較了解了,請直接跳過此節。

1. 字符集與字符編碼概述

簡單來說,字符集就是與特定區域相關的一系列有效字符的有序集合,比如字母、數字、標點符號等。注意關鍵字“有序”,表明集合中的每一個字符都是具有唯一數字編號(碼值)的。不同國家使用的語言文字、符號不一樣,相應的字符集必定也不一樣。比如中國使用漢字,美國使用英語,韓國使用韓文,等等。

字符集是為了信息交互而設計的,最終還是要轉化成計算機的表示法。我們知道,計算機只認識0和1,它對字符集符號不感冒。所以,我們必須想辦法把字符轉化為0和1的序列。我們知道,計算機最小的存儲單位是位(bit),程序中一般使用的最小單位是字節(byte)。為了把字符存儲到計算機中,我們就要考慮用幾個byte幾個bit,考慮每一個bit上是0還是1,考慮存儲和讀取效率,并且必須兼顧整個字符集,這就是字符編碼。

一句話,字符集只關心字符的定義,而字符編碼負責字符的存儲和讀取細節。用三層模式來打比喻的話,字符集是模型層,而字符編碼是業務層。注意:一般常說的GB2312、GBK等其實同時包含了這兩方面的定義

2. 常用中文字符編碼簡介

GB2312

GB2312的全稱是《信息交換用漢字編碼字符集-基本集》,由國家標準總局于1980發布,1981年5月1日施行,中國大陸、新加坡使用此編碼?;炯珍浟?763個漢字,只能顯示簡體漢字。

GBK

1995頒布,全稱是《漢字編碼擴展規范》。在GB2312的其他上,增加了繁體漢字,支持ISO/IEC 10646-1 和GB-13000-1的全部中、日、韓(CJK)字符,共20902個。向下兼容GB2312。

GB18030

全稱是《信息交換用漢字編碼字符集基本集的擴充》,目前兩個版本,分別于2000年和20005年頒布。該字符集收錄了70000多個漢字,包括了藏、蒙古、維吾文等少數民族字符,是我國計算機系統必須遵循的基礎性標準之一。向下兼容GBK和GB2312。

BIG5

臺灣和港臺地區使用的漢字編碼,俗稱“大五碼”,共收錄了13060個漢字。

UTF-8

這是目前使用最多的一種Unicode編碼,是Visual Studio內置的編碼,相信大家一定都不陌生。根據字符碼值的不同,可能用1、2、3個字節表示。

注意,編碼之間一般都不是兼容的。其它編碼在此不作介紹,若想進一步了解字符編碼,請看我收藏的一篇文章:http://blog.csdn.net/tomysea/article/details/6712344

3. 字符串、字符數組和字節數組

C#中的字符串(string)和字符(char)其實都是對象,他們有相應的類String和Char,string和char只是這兩個類的一別名而已,內部都是采用Unicode碼值表示。請注意我說的是碼值,不是編碼。

我們已經知道,Unicode的字符大多是多字節表示的,那么一個char就得用幾個byte來表示。這里我要說的重點是,使用不同的編碼表示字符串,其對應的byte可能是不一樣的。請看下面的代碼,注意輸出字節數部分。UTF-8編碼的字節數是22,而GB2312編碼的字節數是16。

string title = "2012真的來了嗎?"; //字符串

char[] chars = title.ToCharArray(); //字符數組

byte[] bytes = System.Text.Encoding.UTF8.GetBytes(title);

Response.Write(chars.Length + " "); //10 (字符數)

Response.Write(bytes.Length + " "); //22 (UTF-8編碼的字節數)

bytes = System.Text.Encoding.GetEncoding("GB2312").GetBytes(title);

Response.Write(bytes.Length + " "); //16 (GB2312編碼的字節數)

從http請求響應模型說起

http是一個請求/響應的模型,這個我們大家都知道。http請求可以分為請求頭和請求實體兩部分,相應地http響應也可以分為響應頭和響應實體。請求頭或響應頭是瀏覽器與Web服務器通信用的(假定用瀏覽器訪問Web服務器),而實體則是實際發送的數據,比如Form表單的數據、Ajax提交的數據、傳回來的html代碼等。不管是瀏覽器還是Web服務器,在發送實體前都會把它轉換為字節流。明白這一點很重要,因為涉及字節流就一定會與字符編碼有關。

從上面的請求響應模型中我們可以得出一個結論:請求和響應編碼必須嚴格保持一致!為什么呢?這很好理解,瀏覽器和Web服務器是要通信的,如果編碼不一樣的話,勢必會造成許多“誤解”。假設瀏覽器是中國人(不懂E文),而Web服務器是美國人,他們兩個的“編碼”(語言)不一致,悲催的結局不言而喻。

ASP.NET中請求響應編碼的設置

你可以在machine.config或web.config文件指定全局配置,也可以在頁面級特別指定。如果你未手動指定且machine.config中也為空,則默認會讀取計算機上“區域選項”中的設置。

1. 全局配置

在machine.config或web.config文件(根目錄或者子目錄都有效)中的system.web節點中配置globalization節點。如果在根目錄下的web.config配置,則會響應整個網站,若只是在子目錄下配置,則只會響應該目錄及其子目錄。 詳細配置如下:

<system.web>

<globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8"/>

<!--按順序是:文件編碼 請求編碼 響應編碼-->

<!—-fileEncoding會在后面說到-->

<!--后面還有其它配置-->

2. 頁面級的配置

在aspx頁面的Page指令中設置響應編碼

<%@ Page Language="C#" AutoEventWireup="true" ResponseEncoding="utf-8"

CodeBehind="byte.aspx.cs" Inherits="DevKit.Web.test.charset._byte" %>

在aspx頁面中手動指定meta標簽

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

在后臺cs文件中配置

Request.ContentEncoding = System.Text.Encoding.UTF8; //請求編碼

Response.ContentEncoding = System.Text.Encoding.UTF8; //響應編碼 接下來,我們從幾個示例中去體驗亂碼,從而總結出解決亂碼的一般方法。

測試環境

操作系統Windows xp PRofessional SP3 雨林木風版

開發環境:Visual Studio 2008 專業版 + SP1(.NET 3.5)

Web容器:VS集成的Development Server

瀏覽器:IE8 、Firefox 5

實例分析與研究

實例1 aspx頁面提示意外的字符“XXX”,引號里面是亂碼

背景

網站配置了在根目錄配置了文件、請求、響應編碼都為utf-8,頁面成功編譯,沒有任務錯誤。詳細錯誤見下圖:

/

html代碼

<div>

aspx頁面中的中文

<br />后臺的中文變量:<em><%=汽車%></em>

</div>

后臺代碼

view plain

public partial class _byte : System.Web.UI.Page

{

protected string 汽車= "我是凱迪拉克"; //別懷疑,中文變量是可以的:)

protected void Page_Load(object sender, EventArgs e)

{

//...

}

}

分析與解決

既然web.config已經配置了一樣的請求響應編碼,而且頁面級別也沒設置,可以排除這方面的問題了。注意到文件編碼是UTF-8,會不是會文件編碼引起的呢?(提示:這里的文件編碼指的是保存文件時指定的編碼,點擊“另存為&hellip;”,在彈出的窗口中選擇“編碼保存”可以看到)。果然,此aspx頁面的保存編碼為GB2312,與web.config文件不一樣,把它修改為UTF-8。

小提示:UTF-8有兩種編碼:UTF-8(帶簽名)和UTF-8(無簽名)。帶簽名的UTF-8會在文件的開頭寫入“EF BB BF”(16進制),以標示自己采用的編碼格式,這個標志稱為BOM(Byte Order Mark),即字節序。打個比方,UTF-8(帶簽名)戴了?;盏膶W生,就算不認識他的人,一看?;站兔靼琢?;而UTF-8(無簽名)則是沒戴?;盏?。這里的?;站褪俏覀冋f的BOM,一個能夠表明自己身份的標志。

/

小結

這是因為文件的保存編碼與當前網站指定的文件編碼不一致引起的,所以最佳實踐是:手動在web.config中指定文件編碼,并確保所有頁面的保存編碼與web.config一致。

其實最容易出這種問題的是js和CSS文件,如果你用其它工具(比如Dreamweaver)來編寫這些文件卻采用不同的編碼保存,一旦文件包含中文就可能出這樣的錯誤,導致js腳本錯誤,css無效!

實例2 跨頁post提交時接收的Form數據變成了亂碼

背景

有兩個頁面,注冊頁面(register.html)和處理注冊的頁面(handle.aspx),注冊頁面的表單信息以post方式提交到handle.aspx。根目錄的配置的文件編碼、請求編碼和響應編碼都是UTF-8。

register.html頁面的關鍵html

<head>

<title></title>

<meta http-equiv="Content-Type" content="text/html;charset=gb2312" />

</head>

<body>

<form id="form1" name="form1" action="handle.aspx" method="post">

<input type="text" id="txtName" name="txtName" />

<input type="submit" id="btnSubmit" value="Post" />

</form>

handle.aspx頁面關鍵后臺代碼

view plain

protected void Page_Load(object sender, EventArgs e)

{

string name = Request.Form["txtName"];

Response.Write(name);

}

錯誤信息如下

/

分析與解決

這是在提交表單信息過程產生的亂碼,這里就涉及http請求和http響應的編碼問題。我們上面說過,在請求時瀏覽器會把表單信息按指定編碼轉化成字節流發向Web服務器,在服務器ASP.NET會把這些字節流按指定的編碼解碼,以取得表單信息。那么我們就要檢查這兩個頁面的編碼了。仔細檢查之后,發現register.html有這么一行“<meta http-equiv="Content-Type" content="text/html;charset=gb2312" />”,這里手動指定了頁面編碼為GB2312。問題很有可能就出在這里了,把本行刪除之后,handle.aspx頁面成功接收到表單信息。

沒錯,這就是由于兩個頁面的編碼不一樣引起。讓我們再深入一點,仔細看看問題是怎么一步一步產生的吧。register.html的編碼為GB2312,當我們點擊了“Post”按鈕時,瀏覽器會把“我是中文”這幾個字按GB2312的方式編碼成字節流,然后提到到handle.aspx頁面。handle.aspx沒有手動指定編碼,那么他將會采用web.config里面的配置,為UTF-8。它收到請求后,用UTF-8編碼解碼字符流。由于請求用的是GB2312,而接收用的卻是UTF-8,這樣就導致亂碼的產生。通過下面這幅圖可以看到這個過程。

/

小結

所有的頁面(不管是aspx,還是html,或其它)都必須使用相同的編碼。如果涉及跨頁提交,不管是get還是post,更應該嚴格保持相關頁面編碼的一致性。特別是跨站點提交時,更應該注意!

實例3  cookie存取發生亂碼

背景

這是一個舊項目,現在決定增加一個自動登錄的功能。詳細過程是這樣的:

在登錄頁面,用戶登錄成功后把用戶名寫到cookie中。這樣,當用戶再次訪問時,就可以根據cookie判定用戶是否已登錄,從而實現自動登錄。

登錄成功后cookie是這樣保存的

view plain

string userName = "cookie大俠"; //待保存的用戶名

userName = HttpUtility.UrlEncode(userName); //編碼特殊字符,如中文

HttpCookie cookie = new HttpCookie("userName", userName);

Response.Cookies.Add(cookie);

判斷用戶是否已登錄時,代碼是這樣的

view plain

string userName = Request.Cookies["userName"].Value;

userName = Server.UrlDecode(userName);

Response.Write(userName); //總是獲取不到cookie,所以決定打印出來看看

結果在測試讀取cookie的時候,頁面輸出了亂碼,如下圖:

/

分析與解決

全球化信息是這樣配置的

<gl

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲一区www| 一本色道久久综合狠狠躁篇怎么玩| 亚洲天堂精品在线| 神马久久桃色视频| www国产亚洲精品久久网站| 欧美激情xxxx| 欧美一区二区影院| 日韩在线视频中文字幕| 国模精品一区二区三区色天香| 日韩在线免费观看视频| 中文字幕不卡在线视频极品| 国产丝袜高跟一区| 日韩av在线资源| 色婷婷亚洲mv天堂mv在影片| 97在线视频免费| 国产精品成人aaaaa网站| 俺也去精品视频在线观看| 成人在线免费观看视视频| 美女性感视频久久久| 亚洲电影免费观看高清完整版在线观看| 日韩av不卡电影| 国产97在线|日韩| 久久全国免费视频| 国产精品成av人在线视午夜片| 欧美日韩加勒比精品一区| 久久久视频免费观看| www.日韩欧美| 欧美性一区二区三区| 美女久久久久久久久久久| 一本一道久久a久久精品逆3p| 国产噜噜噜噜噜久久久久久久久| 国产精品人人做人人爽| 国产亚洲日本欧美韩国| 欧美又大粗又爽又黄大片视频| 国产精品久久久久久av福利| 成人伊人精品色xxxx视频| 美女扒开尿口让男人操亚洲视频网站| 久久久电影免费观看完整版| 日韩亚洲第一页| 欧美视频二区36p| 亚洲国产福利在线| 国产91网红主播在线观看| 亚洲精品日韩av| 色视频www在线播放国产成人| 久久久久久九九九| 伊人久久男人天堂| 精品亚洲一区二区三区四区五区| 亚洲加勒比久久88色综合| 神马久久桃色视频| 国产亚洲aⅴaaaaaa毛片| 色无极亚洲影院| 亚洲人成绝费网站色www| 久久精品视频99| 欧美福利在线观看| 亚洲精品国产suv| 欧美激情综合色综合啪啪五月| 国产成人综合av| 欧美激情国内偷拍| 国产视频精品在线| 亚洲综合一区二区不卡| 日韩av电影在线播放| 亚洲美女免费精品视频在线观看| 日韩视频亚洲视频| 日韩精品亚洲元码| 成人网页在线免费观看| 国产精品劲爆视频| 亚洲精品视频二区| 91社区国产高清| 在线观看久久av| 亚洲成**性毛茸茸| 日韩成人激情视频| 久久综合亚洲社区| 亚洲理论片在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整| 中文字幕成人精品久久不卡| 色老头一区二区三区在线观看| 97视频在线观看播放| 日韩电影免费在线观看| 国语自产偷拍精品视频偷| y97精品国产97久久久久久| 大桥未久av一区二区三区| 3344国产精品免费看| 欧美在线视频免费播放| 欧美一区视频在线| 97色在线观看免费视频| 亚洲最大av网| 欧洲成人午夜免费大片| 岛国av一区二区| 亚洲а∨天堂久久精品9966| 中文字幕精品在线| 日韩经典一区二区三区| 久久精品99久久久久久久久| 国产精品第七十二页| 欧美另类极品videosbest最新版本| 97视频人免费观看| 亚洲精品网站在线播放gif| 国产亚洲精品久久久久久777| 中文字幕亚洲欧美日韩高清| 亚洲第一精品夜夜躁人人爽| 国产亚洲精品一区二区| 亚洲精品成人免费| 日韩久久午夜影院| 7m精品福利视频导航| 8090理伦午夜在线电影| 欧美精品日韩www.p站| 色阁综合伊人av| 亚洲电影免费在线观看| 欧美日韩一区二区免费视频| 亚洲香蕉伊综合在人在线视看| 精品亚洲一区二区| 久久久国产一区二区| www.欧美精品一二三区| 77777少妇光屁股久久一区| 欧洲精品毛片网站| 久热精品视频在线观看| 国产精品综合不卡av| 成人精品视频99在线观看免费| 欧美日韩中文字幕综合视频| xxxxx成人.com| 中文字幕在线观看亚洲| 国语自产精品视频在线看一大j8| 欧美激情精品久久久久久变态| 国产精品欧美一区二区三区奶水| 一区二区三区四区在线观看视频| 色av吧综合网| 国产aⅴ夜夜欢一区二区三区| 色婷婷av一区二区三区久久| www.久久撸.com| 美女黄色丝袜一区| 欧美日产国产成人免费图片| 日本免费一区二区三区视频观看| 久久精品国产免费观看| 日韩av电影手机在线观看| 精品国产91乱高清在线观看| 亚洲影院色在线观看免费| 日韩美女写真福利在线观看| 国产欧美日韩高清| 国产亚洲视频在线| 91久久久久久国产精品| 热草久综合在线| 精品呦交小u女在线| 欧美成人精品一区二区三区| 久久久久久亚洲精品中文字幕| 久久躁狠狠躁夜夜爽| 久久久久久久久久久久久久久久久久av| 成人看片人aa| 国产精品aaa| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产日韩欧美91| 国产精品视频26uuu| 精品久久久国产| 青草热久免费精品视频| 亚洲人免费视频| 在线看片第一页欧美| 国产一区二中文字幕在线看| 亚洲日韩欧美视频一区| 色在人av网站天堂精品| 91国内产香蕉| 国产极品精品在线观看| 亚洲精品中文字幕av| 亚洲高清免费观看高清完整版| 日韩av免费在线播放| 国产69久久精品成人看| 亚洲日本中文字幕免费在线不卡|