<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      經(jīng)常發(fā)現(xiàn)有人被亂碼困擾著,而我感覺(jué)比較幸運(yùn),很少為此煩惱過(guò)。

      在這篇博客中,我將把我想到的一些與亂碼有關(guān)的經(jīng)驗(yàn)總結(jié)出來(lái),供大家參考。

      頁(yè)面顯示亂碼問(wèn)題

      在一個(gè)網(wǎng)站中,有些頁(yè)面會(huì)正常顯示,然而,有些頁(yè)面會(huì)顯示成亂碼。 如果發(fā)生這種情況,可以檢查一下web.config和文件編碼。

      如果web.config是這樣配置的:

      <globalization fileEncoding="utf-8" />
      

      而文件的編碼不是UTF-8:

      那么就會(huì)有亂碼問(wèn)題。

      注意:反之是不是會(huì)出現(xiàn)亂碼的。
      1. 不設(shè)置fileEncoding,此時(shí)不會(huì)有亂碼現(xiàn)象。
      2. fileEncoding="gb2312",文件以u(píng)tf-8編碼,此時(shí)也不會(huì)有亂碼現(xiàn)象。

      因此,我建議最好讓所有文件都以UTF-8編碼保存,從而解決這類亂碼問(wèn)題。

      AJAX提交的數(shù)據(jù)亂碼問(wèn)題

      AJAX技術(shù)流行了這么多年了,我想現(xiàn)在沒(méi)有幾個(gè)網(wǎng)站不使用這種技術(shù)的。 然而,有些人在使用AJAX時(shí),遇到了亂碼問(wèn)題。

      通過(guò)分析這類亂碼案例中,我發(fā)現(xiàn)幾乎都是采用這種方式向服務(wù)端提交數(shù)據(jù): “key1=” + escape(value1) +“&key2=” + escape(value2)

      這種方法在多數(shù)情況下,的確能夠正常工作,然而遇到一些特殊字符,就行不通了。原因我后面再來(lái)解釋。

      我為這類不正確的方法準(zhǔn)備了一個(gè)示例 (為了保持示例簡(jiǎn)單,我演示一個(gè)拼接URL)
      頁(yè)面代碼如下:

      <p><a id="link2" href="#" target="_blank">escape</a></p>
      
      <script type="text/javascript">
          var str = "aa=1&bb=" + escape("fish li + is me.") + "&cc=" + escape("大明王朝1368");
          $("#link2").attr("href", "/test_url_decode.ashx?method=escape&" + str);
      </script>
      

      服務(wù)端的代碼就是從QueryString讀取那些參數(shù)值,然后輸出。由于代碼實(shí)在太簡(jiǎn)單,就不貼出了。(可下載示例代碼)

      當(dāng)我點(diǎn)擊鏈接時(shí),服務(wù)端返回了這樣的結(jié)果:

      注意:"fish li + is me." 中間的加號(hào)沒(méi)有了。

      解決這個(gè)問(wèn)題有個(gè)簡(jiǎn)單的方法,那就是使用JQuery的$.param()方法,修改后的代碼如下:

      <script type="text/javascript">
          var myobject = { aa: 1, bb: "fish li + is me.", cc: "大明王朝1368" };
          $("#link1").attr("href", "/test_url_decode.ashx?method=param&" + $.param(myobject));
      </script>
      

      另外,我非常反感拼接這種提交數(shù)據(jù):“key1=” + escape(value1) +“&key2=” + escape(value2)
      因?yàn)檫@種代碼的可讀性太差了,在此,我建議在AJAX調(diào)用時(shí),最好直接使用JQuery的$.ajax方法向服務(wù)端提交數(shù)據(jù)。
      請(qǐng)看下面的示例代碼(注意我為data屬性賦值的方式)

      <p><a id="btnTestParam" href="javascript:void(0);">Click me!  【點(diǎn)擊我】</a></p>
      <div id="divResult"></div>
      
      <script type="text/javascript">
          $(function() {
              $("#btnTestParam").click(function() {         
                  $.ajax({
                      url: "/TestParam.ashx", type: "GET", cache: false,
                      data: { id: 2,
                          name: "fish li + is me.",
                          tel: "~!@#$%^&*()_+-=<>?|",                    
                          "x?x!x&x": "aa=2&bb=3&cc=漢字。",  // 特殊的鍵名,值內(nèi)容也特殊。
                          encoding: "見鬼去吧。?& :)",
                          中文鍵名: "大明王朝1368"
                      },
                      success: function(responseText) {
                          $("#divResult").html(responseText);
                      }
                  });
              });
          });
      </script>
      

      運(yùn)行結(jié)果:

      JavaScript中正確的URL編碼方式

      看過(guò)前面的示例,您有沒(méi)有想過(guò):為什么escape不能解決的問(wèn)題,JQuery就能解決呢?

      對(duì)于這個(gè)問(wèn)題,我想還是先來(lái)看看MSDN中關(guān)于escape的說(shuō)明(截圖):

      MSDN說(shuō)的很清楚,我也沒(méi)有必要再做解釋。

      不過(guò),我想有人可能會(huì)問(wèn):我用POST提交數(shù)據(jù)呢?那可是不經(jīng)過(guò)URL的。
      是的,POST數(shù)據(jù)時(shí),參數(shù)沒(méi)有放在URL中,但是,仍然采用URL編碼。
      POST數(shù)據(jù)也采用URL編碼,是因?yàn)椋?b class="redText">表單可以采用GET方式提交,那么數(shù)據(jù)將通過(guò)URL提交給服務(wù)器。
      所以提交的數(shù)據(jù)都要經(jīng)過(guò)URL編碼。

      我們?cè)賮?lái)看一下$.ajax是如何處理數(shù)據(jù)的提交過(guò)程的:

      ajax: function( origSettings ) {
          var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
          
          // ............... 去掉一些無(wú)關(guān)的代碼
      
          // convert data if not already a string
          if (s.data && s.processData && typeof s.data !== "string") {
              // 注意下面這個(gè)調(diào)用
              s.data = jQuery.param( s.data, s.traditional );
          }
      

      再來(lái)看jQuery.param的實(shí)現(xiàn)過(guò)程:

      // Serialize an array of form elements or a set of
      // key/values into a query string
      param: function( a, traditional ) {
          var s = [];
          // ............... 去掉一些無(wú)關(guān)的代碼
          
          // If an array was passed in, assume that it is an array of form elements.
          if ( jQuery.isArray(a) || a.jquery ) {
              // Serialize the form elements
              jQuery.each( a, function() {
                  add( this.name, this.value );
              });
              
          } else {
              // ............... 去掉一些非重點(diǎn)代碼
          }
      
          // Return the resulting serialization
          return s.join("&").replace(r20, "+");
      
          function add( key, value ) {
              // If value is a function, invoke it and return its value
              value = jQuery.isFunction(value) ? value() : value;
              s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
          }
      }
      

      這段代碼的核心就是add函數(shù)的實(shí)現(xiàn)了,它在內(nèi)部調(diào)用了encodeURIComponent()函數(shù)。
      我們應(yīng)該注意JQuery對(duì)數(shù)據(jù)的處理方式:encodeURIComponent(key) + "=" + encodeURIComponent(value);
      JQuery在最后還把%20還替換成 + 號(hào)了。

      在WEB開發(fā)領(lǐng)域,我想大家對(duì)JQuery的權(quán)威應(yīng)該不用懷疑吧? 所以我認(rèn)為JQuery的方法肯定是正確的。

      從JQuery的實(shí)現(xiàn)方式也可以看出:encodeURI()其實(shí)也是不推薦在編碼URL數(shù)據(jù)時(shí)使用的。

      說(shuō)到這里,我要說(shuō)說(shuō)為什么不推薦使用encodeURI。
      encodeURI用于對(duì)整個(gè)URL字符串進(jìn)行編碼,如果某個(gè)參數(shù)值本身包含一些特殊字符。
      例如:key = "x?x/x&x", value = "aa=2&bb=3&cc=漢字。",這個(gè)函數(shù)的結(jié)果將會(huì)不正確。
      它通常用于編碼URL路徑中包含有類似漢字這種場(chǎng)合,不適合處理URL參數(shù)。
      但是,URL路徑中的目錄名與文件名,我們可以選擇英文字符,所以encodeURI通常沒(méi)有機(jī)會(huì)使用。

      ASP.NET中正確的URL編碼方式

      前面介紹了JavaScript中三種URL的編碼方式,在服務(wù)端,ASP.NET有更多的URL編碼方法,
      今天我也把服務(wù)端的編碼也做了個(gè)總結(jié),因?yàn)槲野l(fā)現(xiàn)網(wǎng)上有些資料也是錯(cuò)誤的。

      在ASP.NET中提供三個(gè)URL編碼方法:HttpUtility.UrlPathEncode、HttpUtility.UrlEncode、Server.UrlEncode
      .NET framework還提供了System.Uri這個(gè)類,它也有一些用于URL處理的方法。 比如EscapeUriString,EscapeDataString這二個(gè)方法,可用于URL路徑與參數(shù)的編碼任務(wù)。

      面對(duì)這些方法,我該選擇哪個(gè)?
      我建議在 ASP.NET 中,編碼查詢參數(shù) 時(shí)選擇HttpUtility.UrlEncode(str) ,
      并且在拼接URL時(shí),采用 HttpUtility.UrlEncode(key) + "=" + HttpUtility.UrlEncode(value) 的方法。
      如果要 編碼URL中的路徑,請(qǐng)使用HttpUtility.UrlPathEncode()

      下面我來(lái)解釋前面不建議使用的另外的一些方法的原因:
      1. Server.UrlEncode: 這個(gè)方法其實(shí)也是調(diào)用HttpUtility.UrlEncode,只是它會(huì)盡量使用Response.ContentEncoding所表示的編碼格式, 然而HttpUtility.UrlEncode(str)總是會(huì)使用UTF-8編碼,如果你不希望被字符編碼糾纏,那就應(yīng)該放棄Server.UrlEncode , 畢竟UTF-8編碼才是更好的選擇。
      2. 雖然System.Uri的那二個(gè)編碼方法,也能實(shí)現(xiàn)我們需要的URL編碼任務(wù), 但是,當(dāng)ASP.NET在填充Request.QueryString, Request.Form時(shí),使用的解碼方法是HttpUtility.UrlDecode, 因此,如果你執(zhí)意選擇使用System.Uri的相關(guān)的編碼方法,顯然就不能與解碼方法匹配,后果如何就難說(shuō)了。

      正確的URL編碼方式的總結(jié)

      由于編碼函數(shù)(方法)較多,而且又比較重要,我認(rèn)為有必要再做個(gè)總結(jié)。

      一個(gè)完整的URL可以簡(jiǎn)單地認(rèn)為包含二個(gè)部分:文件路徑(含目錄) 和 查詢參數(shù)(QueryString)
      在編碼時(shí),一定要分開處理。
      編碼文件路徑時(shí),應(yīng)該選擇 encodeURI,HttpUtility.UrlPathEncode 。
      編碼查詢參數(shù)時(shí),應(yīng)該選擇 encodeURIComponent,HttpUtility.UrlEncode,而且拼接方式應(yīng)該是:Encode(key) + "=" + Encode(value)

      絕對(duì)不能先把整個(gè)URL(包含查詢參數(shù))拼接起來(lái)了,再來(lái)考慮該選擇哪個(gè)編碼方法。

      再說(shuō)一遍:在JavaScript中使用escape肯定是錯(cuò)誤的。

      徹底解決encodeURIComponent()與GB2312亂碼問(wèn)題

      前面我建議在JavaScript中使用encodeURIComponent()來(lái)處理提交數(shù)據(jù), 然而encodeURIComponent()在編碼字符時(shí),使用的是UTF-8編碼。 也正因?yàn)檫@個(gè)原因,有人可能會(huì)說(shuō):我的網(wǎng)站使用的編碼方式是gb2312 !

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

      對(duì)于這個(gè)回答,我有時(shí)實(shí)在不想再說(shuō)下去了:你就不能把網(wǎng)站的編碼改成UTF-8嗎?

      現(xiàn)在好了,我設(shè)計(jì)了一種方法,可以解決在GB1212編碼的網(wǎng)站中使用encodeURIComponent(), 這個(gè)方法的設(shè)計(jì)思路比較直接:既然encodeURIComponent()是使用UTF-8編碼, 那么,我們是不是只要告訴服務(wù)端,客戶端提交的數(shù)據(jù)是UTF-8編碼的,此時(shí)服務(wù)端只要識(shí)別后,按照UTF-8編碼來(lái)解碼,問(wèn)題就解決了。

      理清了思路,代碼其實(shí)很簡(jiǎn)單。首先來(lái)看客戶端的代碼。

      $.ajax({
          // 注意下面這行代碼,它為請(qǐng)求添加一個(gè)自定義請(qǐng)求頭
          beforeSend: function(xhr) {    xhr.setRequestHeader("x-charset", "utf-8"); },
          
          url: "/TestParam.ashx", type: "GET", cache: false,
          data: { id: 2,
              name: "fish li + is me.",
              tel: "~!@#$%^&*()_+-=<>?|",                    
              "x?x!x&x": "aa=2&bb=3&cc=漢字。",  // 特殊的鍵名,值內(nèi)容也特殊。
              encoding: "見鬼去吧。?& :)",
              中文鍵名: "大明王朝1368"
          },
          success: function(responseText) {
              $("#divResult").html(responseText);
          }
      });
      

      注意:在原來(lái)的基礎(chǔ)上,我只加了一行代碼:

      beforeSend: function(xhr) {    xhr.setRequestHeader("x-charset", "utf-8"); },
      

      再來(lái)看服務(wù)端代碼。我寫了一個(gè)HttpModule來(lái)統(tǒng)一處理這個(gè)問(wèn)題。

      public class ContentEncodingModule : IHttpModule
      {
          public void Init(HttpApplication app)
          {
              app.BeginRequest += new EventHandler(app_BeginRequest);
          }
      
          void app_BeginRequest(object sender, EventArgs e)
          {
              HttpApplication app = (HttpApplication)sender;
              HttpWorkerRequest request = (((IServiceProvider)app.Context)
                                  .GetService(typeof(HttpWorkerRequest)) as HttpWorkerRequest);
      
              // 注意:我并沒(méi)有使用 app.Request.Headers["x-charset"]
              // 因?yàn)椋航^大部分程序不訪問(wèn)它,它將一直保持是 null,
              // 如果我此時(shí)該問(wèn)這個(gè)集合,會(huì)導(dǎo)致填充它。
              // 我認(rèn)為填充Headers集合比我下面的調(diào)用的成本要高很多,
              // 所以,直接通過(guò)HttpWorkerRequest讀取請(qǐng)求頭對(duì)性能的損耗會(huì)最小。
              
              string charset = request.GetUnknownRequestHeader("x-charset");
              if( string.Compare(charset, "utf-8",  StringComparison.OrdinalIgnoreCase) == 0 )
      
                  // ASP.NET在填充QueryString,Form時(shí),會(huì)訪問(wèn)Request.ContentEncoding做為解碼時(shí)使用的字符編碼
                  app.Request.ContentEncoding = System.Text.Encoding.UTF8;
          }
      

      改造后的結(jié)果是:除非客戶端明確添加"x-charset"請(qǐng)求頭,否則還是按原來(lái)的方式處理,對(duì)于服務(wù)端代碼來(lái)說(shuō),完全不用修改。

      說(shuō)明:
      1. 如果網(wǎng)站的提交全部采用JQuery,也可以統(tǒng)一設(shè)置,這是JQuery支持的功能。
      2. 如果使用JQuery1.5以上版本,也可以寫成:headers: {"x-charset" : "utf-8"}
      3. 就算以后網(wǎng)站使用UTF-8編碼,所有代碼不需要做任何修改。

      Cookie亂碼問(wèn)題

      前段時(shí)間,有人在博客的評(píng)論中問(wèn)我:asp.net服務(wù)器端寫中文cookie,js客戶端讀取時(shí)亂碼。

      其實(shí)這個(gè)問(wèn)題還是比較好解決的,方法是:寫Cookie時(shí)用HttpUtility.UrlEncode編碼,然后在客戶端使用decodeURIComponent把內(nèi)容轉(zhuǎn)回來(lái)就可以了。 在此,我推薦使用jquery.cookie.js這個(gè)插件來(lái)讀寫Cookie。 示例代碼如下(前端):

      $(function() {
          var cookie = $.cookie("TestJsRead");
          $("#cookieValue").text(cookie);
      });
      

      服務(wù)端代碼:

      cookie = new HttpCookie("TestJsRead", HttpUtility.UrlEncode("大明王朝1368"));
      Response.Cookies.Add(cookie);
      

      下載文件名亂碼問(wèn)題

      有時(shí)我們需要在程序運(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建文件,并讓用戶下載這個(gè)在運(yùn)行時(shí)產(chǎn)生的文件, 然而,有時(shí)候用戶會(huì)要求程序能生成一個(gè)默認(rèn)的文件名,方便他們保存。 此時(shí),我們只需要設(shè)置Content-Disposition這個(gè)響應(yīng)頭,并給一個(gè)默認(rèn)的文件名就可以了。

      一般說(shuō)來(lái),我們只要讓默認(rèn)的下載文件名是英文及數(shù)字,問(wèn)題永遠(yuǎn)不會(huì)出現(xiàn), 但是,有時(shí)候用戶可能要求默認(rèn)的文件中包含漢字, 最終,問(wèn)題也隨之發(fā)生了。 請(qǐng)看下面的代碼:

      public void ProcessRequest(HttpContext context)
      {
          byte[] fileContent = GetFileContent();
          context.Response.ContentType = "application/octet-stream";
      
          string downloadName = "ClownFish性能測(cè)試結(jié)果.xlsx";
          string headerValue = string.Format("attachment; filename=\"{0}\"", downloadName);
          context.Response.AddHeader("Content-Disposition", headerValue);
      
          context.Response.OutputStream.Write(fileContent, 0, fileContent.Length);
      }
      

      這段代碼在我的FireFox, Opera, Safari, Chrome都能正常運(yùn)行,其中FireFox顯示的下載對(duì)話框也是我期待的樣子:

      遺憾的是,在我的IE8中是這樣的:

      對(duì)于這個(gè)亂碼問(wèn)題,我們需要把代碼做一點(diǎn)修改:

      string downloadName = "ClownFish性能測(cè)試結(jié)果.xlsx";
      if( context.Request.Browser.Browser == "IE" )
          downloadName = HttpUtility.UrlPathEncode(downloadName);
      

      此時(shí)IE顯示的文件名就不是亂碼了。

      說(shuō)明:我的機(jī)器環(huán)境是 Windows Server 2003 SP2, 用于測(cè)試的瀏覽器版本分別為:

      多語(yǔ)言數(shù)據(jù)的亂碼問(wèn)題

      現(xiàn)在還有一種亂碼問(wèn)題是:同一個(gè)程序供多種不同字符集(語(yǔ)言)的用戶在使用。
      例如:程序是簡(jiǎn)體中文的,此時(shí),繁體中文的用戶無(wú)法保存繁體漢字(就算簡(jiǎn)體漢字能正常顯示)。

      當(dāng)發(fā)現(xiàn)這種現(xiàn)象時(shí),需要檢查一下數(shù)據(jù)庫(kù)的字段類型,是否是Unicode或者UTF-8, 因?yàn)楫?dāng)數(shù)據(jù)字段的字符集不支持多種語(yǔ)言時(shí),亂碼問(wèn)題必定產(chǎn)生。

      我建議在使用SQL SERVER時(shí),保存文字的字段都使用N開頭的類型, 如:nvarchar, nchar,除非明確知道要保存郵政編碼或者md5值,才有必要使用char(xxx)這種數(shù)據(jù)類型。 類似的,在MySQL中,我建議使用UTF-8

      亂碼問(wèn)題的總結(jié)

      ASP.NET的亂碼問(wèn)題一般與二個(gè)因素有關(guān):
      1. 選擇了不恰當(dāng)?shù)淖址幋a,如:gb2312
      2. 選擇了不正確的URL編碼方法,如:escape()

      因此,解決方案其實(shí)也不難:
      1. 字符編碼選擇 utf-8 ,包含文件編碼,請(qǐng)求/響應(yīng)編碼,數(shù)據(jù)庫(kù)字段類型。
      2. URL編碼方法選擇encodeURIComponent,再次強(qiáng)烈推薦直接使用JQuery

      我一直認(rèn)為:正確的方法可以讓我在無(wú)形中避開許多問(wèn)題。
      如果你還為亂碼問(wèn)題而煩惱,我建議你先想想你是否選擇了不正確的編碼(方法)。

      點(diǎn)擊此處下載示例代碼

      posted on 2012-10-14 23:26  Fish Li  閱讀(77182)  評(píng)論(99)    收藏  舉報(bào)
      主站蜘蛛池模板: V一区无码内射国产| 莆田市| 免费无码高H视频在线观看| 亚洲色av天天天天天天| 中文字幕人妻色偷偷久久| 国产亚洲精品VA片在线播放| 中文字幕有码日韩精品| 女人与牲口性恔配视频免费| 又爽又黄又无遮掩的免费视频| 18禁亚洲深夜福利人口| 亚洲国产精品午夜福利| 免费无码又黄又爽又刺激| 国产97人人超碰caoprom| 国产一区二区三区小说| 蜜臀av一区二区三区日韩| 日本亚洲中文字幕不卡| 柠檬福利第一导航在线| 色综合久久久久综合体桃花网| 国产成人精品一区二区| 国产精品区一区第一页| 丁香婷婷在线观看| 玖玖在线精品免费视频| 日韩AV高清在线看片| 免费大片av手机看片高清| 国产极品丝尤物在线观看| 熟女性饥渴一区二区三区| 国产真实露脸乱子伦原著| 日本亲近相奷中文字幕| 麻豆tv入口在线看| 九九成人免费视频| 国产无遮挡免费真人视频在线观看| 一区二区三区午夜福利院| 内射老阿姨1区2区3区4区| 久久精品道一区二区三区| 欧美精品人人做人人爱视频| 久久久久青草线蕉综合超碰| 国产自在自线午夜精品| 亚洲性日韩精品一区二区| 中文字幕少妇人妻精品| 亚洲精品国模一区二区| 成在人线av无码免费|