久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

中文化和國(guó)際化問題權(quán)威解析之五:URL編碼/Misc...

 -ー意孤行ノ 2009-03-19

通過前面中文化,、國(guó)際化問題解決的系列1-4,相信大家對(duì)字符集,、字符編碼,、字符解碼、字符亂碼,、Java中文問題解決等都有了一個(gè)比較清晰的認(rèn)識(shí),;但文中的信息并非包羅萬(wàn)象,結(jié)合到自己平時(shí)對(duì)于字符集,、編碼相關(guān)的一些疑惑,,本篇對(duì)一些前文中并未提及的一些問題進(jìn)行補(bǔ)充,以便讓該系列更加完善和全面,;本文主要解決以下兩個(gè)問題:其一,,解決UltraEdit菜單中的 文件 -> 轉(zhuǎn)換 子菜單中涉及的一些名詞疑惑,主要涉及EBCDIC ,、OEM字符集,、ANSI字符集、HZ編碼等,;其二,,補(bǔ)充關(guān)于URL編碼相關(guān)的一些知識(shí)點(diǎn),涉及瀏覽器,、Web服務(wù)器設(shè)置,、Servlet規(guī)范等;

更多的與字符集相關(guān)的專業(yè)詞匯簡(jiǎn)介

相信很多同學(xué)都有在用UltraEdit這個(gè)文本編輯器軟件,,從菜單 文件 --> 轉(zhuǎn)換 進(jìn)入即可看見很多的字符集間的轉(zhuǎn)換子菜單,,不同版本間可能會(huì)有些差異,可以參考下圖:

 

從上圖中我們可以看到很多前面已經(jīng)提及的一些詞匯,,比如ASCII,、Unicode [Big Endian/Little Endian]、UTF-8等,;但還有一些未提及的,,下面就逐個(gè)介紹下:

  • l DOS/UNIX/MAC間的轉(zhuǎn)換
    這幾項(xiàng)和字符集無(wú)關(guān),主要是由于各個(gè)系統(tǒng)對(duì)行結(jié)束字符的要求不一樣,體現(xiàn)在:Mac格式只要求回車,、Unix只要求換行,、DOS則要求回車、換行 二者組合,;這幾個(gè)命令要做的就是對(duì)這幾個(gè)特殊字符進(jìn)行相應(yīng)替換,;
  • l EBCDIC (Extended Binary Coded Decimal Interchange Code):
    他是與ASCII同時(shí)期的一種字符編碼,主要用于IBM計(jì)算機(jī)中,;它采用8位碼, 有256個(gè)編碼狀態(tài), 但只選用其中一部分,。0-9十個(gè)數(shù)字符的高4位編碼為1111, 低4位仍為0000-1001。大,、小寫英文字母的編碼同樣滿足正常的排序要求, 而且有簡(jiǎn)單的對(duì)應(yīng)關(guān)系, 即同一個(gè)字母的大小寫的編碼值僅最高的第二位的值不同, 易于識(shí)別與變換,。
  • l OEM字符集
    由于ASCII碼只利用了低7位,第8位沒有被使用,,而隨著計(jì)算機(jī)的發(fā)展,,很多原始設(shè)備制造商(當(dāng)時(shí)最有名的應(yīng)該就是IBM了)覺得ASCII碼已經(jīng)無(wú)法滿足需求了,所以他們各自對(duì)第8位進(jìn)行了自定義擴(kuò)展,,從而形成了五花八門的OEM字符集,;由于這些擴(kuò)展都是不通用的,只有各自能夠解釋,,這些不兼容的擴(kuò)展又叫做代碼頁(yè)(Code Page),,在同一臺(tái)機(jī)器中,通過不同的代碼頁(yè)就可以實(shí)現(xiàn)系統(tǒng)間信息的轉(zhuǎn)換了,;
  • l ANSI字符集
    正如前面提到的,,眾多的OEM廠商對(duì)第8位進(jìn)行了自定義擴(kuò)展;但更加夸張和恐怖的事情是,,隨著計(jì)算機(jī)進(jìn)入亞洲,,此時(shí)卻發(fā)現(xiàn)整整用完8位也無(wú)法將所有的他們需要的語(yǔ)言字符;于是在ASCII的基礎(chǔ)上他們?cè)俅芜M(jìn)行了擴(kuò)展,,從而產(chǎn)生了雙字節(jié)字符集DBCS(double byte character set),,我們常見的國(guó)標(biāo)系列GB2312/GBK/BIG5......都屬于此類;這些字符集有一個(gè)共同的特點(diǎn):完全兼容ASCII,!這是ANSI系列和Unicode系列最大的不同點(diǎn),;這類型基于ASCII碼進(jìn)行擴(kuò)展的多字節(jié)字符集MBCS統(tǒng)稱為ANSI字符集,;注意:ANSI字符集之間也是無(wú)法直接識(shí)別的,,需要進(jìn)行自定義轉(zhuǎn)換,;
  • l 提到國(guó)標(biāo)系列,在此我還想提一個(gè)編碼:HZ,,HZ是漢字的簡(jiǎn)稱?
    他是基于GB字符集的一種簡(jiǎn)體中文編碼,在新加坡被廣泛使用,;編碼規(guī)則為:他將每個(gè)字節(jié)中的第8位(在GB字符集中該位為1)屏蔽,,只保留低7位,并將經(jīng)過變換后的部分用~{,、~}括起來(lái),;解碼的時(shí)候只需要將括號(hào)對(duì)里面的部分高位還原成1即可;這樣就可以在互聯(lián)網(wǎng)上廣泛的傳輸了,,而不必受制于某些系統(tǒng)只能接收基于ASCII碼的字符,;

URL編碼

基于Java開發(fā)的Web應(yīng)用URL組成如下:
http://domain:port/contextPath/servletPath/pathInfo?queryString
其中各個(gè)部分含義如下:
Domain、Port:分別是域名和端口,;
contextPath:應(yīng)用上下文路徑,,默認(rèn)為應(yīng)用名稱,比如我們的apps,;但可以通過應(yīng)用服務(wù)器的相關(guān)配置進(jìn)行修改,,一般線上環(huán)境會(huì)修改成/,此時(shí)相當(dāng)于contextPath為空,;
servletPath:Servlet路徑,,一般在應(yīng)用的web.xml文件中配置servlet-mapping;但由于現(xiàn)在的web應(yīng)用一般都會(huì)用一些框架,,比如Struts,、Webwork等,此時(shí)各框架都會(huì)對(duì)此進(jìn)行封裝,,會(huì)在另外的配置文件中進(jìn)行設(shè)置,;但原理都是一樣的;
pathInfo:可以理解為最終接收用戶請(qǐng)求的具體執(zhí)行類,,比如我們常說的Action,;
queryString:get方式傳入的請(qǐng)求參數(shù);
以上各個(gè)部分中可能存在中文問題的是pathInfo,、queryString兩個(gè)部分,;

首先,我們來(lái)看下Servlet中和URL相關(guān)的一些api及其注意事項(xiàng):
HttpServletRequest.setCharacterEncoding(); //僅僅只適用于設(shè)置post提交的request body的編碼而不是設(shè)置get方法提交的queryString的編碼,。該方法還告訴應(yīng)用服務(wù)器應(yīng)該采用什么編碼解析post傳過來(lái)的內(nèi)容,;注意:若沒有設(shè)定characterEncoding,則使用ISO-8859-1來(lái)解碼用戶輸入的表單,,而不是使用系統(tǒng)默認(rèn)的編碼,。
HttpServletResponse.setContentType();      //告訴瀏覽器網(wǎng)頁(yè)中數(shù)據(jù)是什么編碼;表單提交時(shí),,根據(jù)ContentType指定的charset對(duì)表單中的數(shù)據(jù)編碼,,然后發(fā)送給服務(wù)器,。
HttpServletRequest.getParameter("name");   //返回的字符串為:queryString(包括get和post),其值經(jīng)過Servlet服務(wù)器URL Decode過的,,默認(rèn)編碼來(lái)源于應(yīng)用服務(wù)器中的配置,,比如tomcat中server.xml的URIEncoding。
HttpServletRequest.getPathInfo();          //返回的字符串為:pathinfo,;由Servlet服務(wù)器解碼(decode)過的,。默認(rèn)編碼同上,tomcat中可設(shè)置useBodyEncodingForURI,。
HttpServletRequest.getRequestURI();        //返回的字符串為:contextPath/servletPath/pathinfo,;注意是瀏覽器提交過來(lái)的原始數(shù)據(jù),未被Servlet服務(wù)器URL Decode過,。

對(duì)URL編碼【URL Encoding/Percent Encoding】時(shí),,使用以下規(guī)則:
字母數(shù)字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不變,。
特殊字符 ".",、"-"、"*" 和 "_" 保持不變,。
空格字符 " " 轉(zhuǎn)換為一個(gè)加號(hào) "+",。
所有其他字符都是不安全的,因此首先使用一些編碼機(jī)制將它們轉(zhuǎn)換為一個(gè)或多個(gè)字節(jié),。然后每個(gè)字節(jié)用一個(gè)包含 3 個(gè)字符的字符串 "%xy" 表示,,其中 xy 為該字節(jié)的兩位十六進(jìn)制表示形式。推薦的編碼機(jī)制是 UTF-8,。但是,,出于兼容性考慮,如果未指定一種編碼,,則使用相應(yīng)平臺(tái)的默認(rèn)編碼,。

假定我們待請(qǐng)求URL為:http://localhost:8080/example/中國(guó)?name=中國(guó);
Html內(nèi)content-type或meta中的charset=GBK,;文件格式為ANSI/ASCII,;
URL中的兩個(gè)漢字"中國(guó)"的各字符集下的編碼為:

漢字 編碼 二進(jìn)制表示
中國(guó) UTF-8 0xe4 0xb8 0xad 0xe5 0x9b 0xbd[-28, -72, -83, -27, -101, -67]
中國(guó) GBK 0xd6 0xd0 0xb9 0xfa[-42, -48, -71, -6]
中國(guó) ISO8859-1 0x3f 0x3f[63, 63][??]

對(duì)于Get方式的URL請(qǐng)求有兩種情況,其一:用戶直接在瀏覽器地址欄中輸入U(xiǎn)RL,,此時(shí)瀏覽器沒有編碼可參考,,直接用瀏覽器的默認(rèn)編碼進(jìn)行解析并提交到服務(wù)端;其二:在form表單內(nèi)提交,,只是form屬性method為GET,,此時(shí)瀏覽器會(huì)參考目前html中對(duì)編碼的相關(guān)設(shè)置進(jìn)行解析,比如content-type或meta中的charset,。

以下就重點(diǎn)講講第二種方式的提交:
GET方式form submit:瀏覽器會(huì)對(duì)URL進(jìn)行URL encoding,,然后發(fā)送給服務(wù)器,。

  • 對(duì)于中文IE,如果在高級(jí)選項(xiàng)中選中總以UTF-8發(fā)送(默認(rèn)方式),則PathInfo在URL Encoding時(shí)按照UTF-8編碼,;QueryString按照GBK編碼,。
    此時(shí)提交是:GET /example/%E4%B8%AD%E5%9B%BD?name=%D6%D0%B9%FA
  • 對(duì)于中文IE,如果在高級(jí)選項(xiàng)中取消總以UTF-8發(fā)送,則PathInfo和QueryString在URL encoding時(shí)按照GBK編碼,。
    此時(shí)提交是:GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
  • 對(duì)于中文firefox、Chrome,,因?yàn)闆]有類似IE中的這種設(shè)置選項(xiàng),,所以這兩種瀏覽器中對(duì)pathInfo的編碼規(guī)則沒有做特殊處理,MS是和queryString采取同樣的編碼規(guī)則,;在本例中的假設(shè)情況下:pathInfo和queryString在URL encoding時(shí)都按照GBK編碼,。
    此時(shí)提交是:GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA

很顯然,不同的瀏覽器以及同一瀏覽器的不同設(shè)置,,會(huì)影響最終URL中PathInfo的編碼,,該編碼可能不會(huì)由我們應(yīng)用來(lái)控制;對(duì)于queryString,,則是可以由我們的應(yīng)用來(lái)完全控制的,,對(duì)于上面的事例:中文的IE和FIREFOX都是采用GBK編碼queryString。

若調(diào)整下上例中的假設(shè)條件,,設(shè)置Html內(nèi)content-type或meta中的charset=UTF-8,;
此時(shí)在IE中queryString會(huì)按照UTF-8進(jìn)行編碼,即name=%E4%B8%AD%E5%9B%BD,;
但是在非IE(Firefox,、Chrome)中,此時(shí)提交時(shí)URL中會(huì)以中文直接提交,,即name=中文,;此時(shí)服務(wù)端的web服務(wù)器上肯定要進(jìn)行相應(yīng)的編碼配置,否則肯定會(huì)出現(xiàn)亂碼,;

若設(shè)置Html內(nèi)content-type或meta中的charset=ISO-5899-1,;
此時(shí)在IE、Firefox,、Chrome中queryString都被用ISO-5899-1編碼了,,即name= %26%2320013%3B%26%2322269%3B;
對(duì)于編碼串中的%26,、%3B應(yīng)該是百分號(hào)編碼【Percent Encoding】中的保留字符,,分別對(duì)應(yīng)&、;,,兩者之間是經(jīng)過編碼的十進(jìn)制碼,;對(duì)于這點(diǎn)偶也不是十分肯定,?要是有同學(xué)比較清楚,請(qǐng)告訴偶下,,thx,。

POST方式提交:表單中的參數(shù)值對(duì)是通過request body發(fā)送給服務(wù)器,此時(shí)瀏覽器會(huì)根據(jù)網(wǎng)頁(yè)的ContentType("text/html; charset=GBK")中指定的編碼進(jìn)行對(duì)表單中的數(shù)據(jù)進(jìn)行編碼,,然后發(fā)給服務(wù)器,。
在服務(wù)器端的程序中我們可以通過Request.setCharacterEncoding() 設(shè)置編碼,然后通過request.getParameter獲得正確的數(shù)據(jù),。

小結(jié):

  • 1. URL中的PathInfo字符串的編碼和解碼是由瀏覽器和應(yīng)用服務(wù)器的配置決定的,,我們的程序不能設(shè)置,不要期望用request.setCharacterEncoding()方法能設(shè)置URL中pathInfo解碼時(shí)的字符集,,這在servlet規(guī)范里面有說明,。
  • 2. URL中如果含有中文等非ASCII字符,則瀏覽器會(huì)對(duì)它們進(jìn)行URLEncode,。為了避免瀏覽器采用了我們不希望的編碼,,所以最好不要在URL中直接使用非ASCII字符,而采用URL Encode編碼過的字符串%xy,;
    對(duì)此建議URL:http://localhost:8080/example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
  • 3. URL中PathInfo和QueryString應(yīng)該采用相同的編碼,,pathInfo最好不要用中文;因?yàn)椴煌瑸g覽器對(duì)URL中PathInfo和QueryString編碼時(shí)采用的字符集不同,,但應(yīng)用服務(wù)器對(duì)URL通常會(huì)采用相同的字符集來(lái)解碼,。
  • 4. URL中的queryString的編碼方式是依賴于網(wǎng)頁(yè)的contentType、meta中的charset字符集設(shè)置的,,記住這點(diǎn)對(duì)于form get方式提交亂碼問題排查是非常有好處的,。
  • 5. 頁(yè)面文件的編碼最好和頁(yè)面內(nèi)設(shè)置的charset一致,因?yàn)槲覀兛赡茉陧?yè)面內(nèi)部有很多中文,,若編碼不一致,,則可能出現(xiàn)在編輯器內(nèi)看著是正常的,但到了瀏覽器上則變成了亂碼(雖然頁(yè)面顯示為亂碼,,但這并不意味著在form submit時(shí)數(shù)據(jù)會(huì)有問題,,很可能出現(xiàn)負(fù)負(fù)為正的情況);這點(diǎn)在前面寶寶的文檔中也有說明,;
    另外,,文件的編碼很可能會(huì)影響問題的排查;比如上例中我們就已說明:文件格式為ANSI/ASCII,,若文件格式為Unicode/UTF-*系列,,那測(cè)試結(jié)果會(huì)不會(huì)不一樣呢?大家可以自行測(cè)試下,;
  • 6. 服務(wù)端URL Encode時(shí)最好指定字符集,,否則encoding的字符集依賴于本地系統(tǒng)的默認(rèn)編碼,。可以參考javadoc:
    http://gceclub./Java_Docs/html/zh_CN/api/java/net/URLEncoder.html

相關(guān)文檔參考:
字符,,字節(jié)和編碼:http://www./zh/encoding.htm
各種字符集和編碼詳解:http://blog.csdn.net/ancky/archive/2008/01/11/2034809.aspx
深入淺出URL編碼:http://blog.csdn.net/yzhz/archive/2007/07/03/1676796.aspx
javascript html 相關(guān)編碼問題研究:http:///log/fpev3c89q.html
J2EE Web組件中中文及相關(guān)的問題(系列):http://blog.csdn.net/whodsow/archive/2003/10/27/19465.aspx

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多