中文問題是和做WEB的程式員形影不離的, jsp頁面的中文問題,Url傳參的中文問題,request取值的中文問題…….現在Ajax日趨成熟了,它的中文問題也一樣浮出水面了。
其實萬變不離其宗,中文問題就是編碼問題,我們知道所有的字元集,不管是英文,操作符,標點符號,最基本的編碼方式就是ISO-8859-1,中文的編碼方式現在最常用的就是GBK,GB2312,UTF-8三種,這三種都是繼承自ISO-8859-1,所以只要把握了底層最基本的編碼,不管是ajax還是struts,中文問題的解決都是一脈相承的。
好,那我們來看看一個完整的ajax流程,一步步的來剖析它的中文問題及解決方案。
首先是頁面:JSP頁面的編碼方式決定了頁面上中文的顯示,這點應該都很清楚。要使jsp頁面中文不是亂碼
這樣就可以指定該頁面的中文編碼為UTF-8了(用UTF-8的原因是因為xml的編碼方式都是UTF-8的,而ajax是和xml緊密相連的,jsp頁面及之後的ajax請求參數的提交,servlet中往用戶端寫輸出資料流都統一為UTF-8,對於ajax的處理是相當有必要的)。
<%@ page contentType="text/html;charset=UTF-8"%>
然後就是ajax請求時傳遞的中文了,我們知道ajax請求雖是非同步,但它也是一個HTTP請求,所以它也會有HTTP Header, URL等這些參數,如果我們發送ajax請求時需要傳遞中文參數,最好的辦法就是在用戶端就完成對HTTP請求中中文資料的編碼,否則瀏覽器預設是用ISO-8859-1編碼發送http請求的。這裡說的中文資料包括兩部分:
一是Http Header中的URL參數,比如
Tomcat配置URI的方法如下(Tomcat5.X以上必須設定該參數,否則它會採用一種非ISO-8859-1的編碼方式,這樣即使服務端再request.setCharaterEncoding()都沒法了,必定亂碼!):
<a href=”test.jsp?param1=中文參數1¶m2=中文參數2>
這類傳參時的中文,這種中文編碼的解決辦法最好是讓應用伺服器來做,比如我們最常用的
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" acceptCount="100" debug="0" connectionTimeout="20000" proxyPort="80" disableUploadTimeout="true" URIEncoding="UTF-8"/>
二是http請求中body部分的中文,這就是表單中的資料了,這部分ajax的HttpRequest有專門的方法設定:如下所示:
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
這樣Http Body部分的中文就都已經編碼為UTF-8了。,
好了,既然用戶端瀏覽器發送ajax請求時請求的內容都已經用UTF-8編碼了,那麼傳到服務端的資料就已經是編碼後的中文資料了,服務端的request就不需要通過request.SetCharaterEncodin()方式再設定編碼格式了。這點跟Struts是最大的區別,我們通常看到的Struts對編碼問題的解決是通過過濾器,即對所有發送到後台服務端的請求都實現通過這個過濾器,在這個過濾器中設定request的編碼方式。實際上這兩種方式是殊途同歸的,ajax是在用戶端就做了編碼,發送到服務端當然不需要設定了,而Struts在用戶端submit的時候沒有做任何設定,那發送到服務端的肯定是ISO-8859-1的資料了,所以需要在過濾器中指定一下,這樣request 發現其中的資料有中文,就會對其進行編碼了。
接下來服務端完成了商務邏輯,要將結果返回給用戶端,那麼同樣的問題來了,還記得文中最開頭的時候我們在jsp頁面設定的嗎?那裡面指定的是UTF-8編碼,那麼我們現在往jsp頁面寫輸出資料流的時候是不是也應該編碼成和頁面的中文編碼方式一致呢?答案是肯定的,我們的ajax返回資料時應該加上response的ContentType:
contentType
!這樣向用戶端寫的資料中的中文也是UTF-8編碼了,用戶端js指令碼擷取到request.responseXML也好,responseText也好,裡面的資料都不會有亂碼了。
response.setContentType("text/xml;charset=UTF-8");
response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
PrintWriter out = response.getWriter();
out.write(outXML);
out.flush();
out.close();
OK
至此ajax的中文問題已全部解決,從最初的jsp頁面看過來,中文就是一個編碼方式的問題,出現亂碼的原因大部分是在錯誤的時間,錯誤的地點進行了編碼的操作,且編碼的類型一會兒GBK,一會兒GB2312,一會兒UTF-8,當然資料會亂掉了。實際上如果熟悉了HTTP協議,對編碼的問題有一個清晰的瞭解,按照上述方法處理,中文是一點問題都沒有的。