標籤:style blog http java color 使用
ajax亂碼解決總結
第一,javascript沿用java的字元處理方式,內部是使用unicode來處理所有字元的,
第二,utf-8是每個漢字(unicode字元)用3個位元組來儲存。
第三,用utf-8來send資料是不會出現亂碼的,是背景程式沒有正確解碼才會出現亂碼。
第四,ajax發送資料的時候如果修改 Content-Type 為 application/x-www-form-urlencoded",肯定是用post方式,而“太大的資料往往會出錯”是用GET方式發送資料造成的。
第五,用vbscript寫的函數是用來把資料轉成gbk編碼(作業系統預設的編碼方式。如果在繁體系統上就是big5之類的編碼)的,而不是gb2312,兩者的編碼字元數量相差3倍左右。
第六,用cookie來發送資料,一是很容易溢出,二是要不停的擦屁股,否則cookie裡面的資料在每個http請求(包括圖片和指令碼請求)中都會被發送。三是並發幾個http請求的時候,沒有辦法指定那個cookie是要發送給那個http請求的。
------------------------
用AJAX 來GET回一個頁面時,RESPONSETEXT裡面的中文多半會出現亂碼,這是因為xmlhttp在處理返回的responseText的時候,是把 resposeBody按UTF-8編碼進解碼考形成的,如果伺服器送出的確實是UTF-8的資料流的時候漢字會正確顯示,而送出了GBK編碼流的時候就 亂了。解決的辦法就是在送出的流裡面加一個HEADER,指明送出的是什麼編碼流,這樣XMLHTTP就不會亂搞了。
PHP:header(‘Content-Type:text/html;charset=GB2312‘);
ASP:Response.Charset("GB2312")
JSP:response.setHeader("Charset","GB2312");
方法一 (這種方法不怎麼可靠) 向伺服器發送請求,在伺服器端加入:
String string = request.getParmater("parmater");
string = new String(string.getBytes("ISO8859-1"),"GBK");
伺服器向用戶端發送報文:
String static CONTENT_TYPE = "text/html;charset=GBK";
response.SetContentType(CONTENT_TYPE);
方法二 (不推薦使用,URLDecoder.decode()與新瀏覽器不相容)Ajax POST 中文亂碼解決
看了好多篇文章,最終還是看到一篇,解決了自己的問題.
ajaxpost.js var myRequest; // Variable to hold request object function mysubmit()...{ if (window.XMLHttpRequest) ...{ myRequest = new XMLHttpRequest(); // Standards-compliant browsers } else if (window.ActiveXObject) ...{ myRequest = new ActiveXObject("Msxml2.XMLHTTP"); // For IE }
var post="name="+document.getElementById("postval").value; post=encodeURI(post); post=encodeURI(post); //最重要的部分,兩次調用encodeURI ,就是編碼兩次 myRequest.open("POST","servlet/Display",false); //myRequest.setRequestHeader("contentLength",post.length); myRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); myRequest.send(post); var res=myRequest.responseText;//接收返回的資料 document.getElementById("display").innerHTML=res; }
servlet
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException ...{
response.setContentType("text/html"); response.setCharacterEncoding("GBK"); PrintWriter out = response.getWriter(); String name=request.getParameter("name"); name=URLDecoder.decode(name,"utf8"); //post 傳遞的時候,一定是用utf8編碼的,url 自己可以設定 System.out.println(name); out.println(name); out.flush(); out.close(); }
分析:當調用request.getParameter()函數時,會自動進行一次URI的解碼過程,調用時內建的解碼過程會導致亂碼出現。而URI 編碼兩次後,request.getParameter()函數得到的是原資訊URI編碼一次的內容。再用可控的解碼函數 java.net.URLDecoder.decode()就可解出原始的正確的資訊。 |
方法三(還可以)
AJAX提交資料亂碼,返回資料亂碼的解決方案
隨著AJAX的流行,亂碼問題也開始困擾著許多剛開始使用它的程式員,幸好我之前對JSP亂碼有過一點研究,在遇到AJAX後,並沒有給我帶來多大的困擾,在此將我的一些心得共用給大家。
萬變不離其宗,AJAX的亂碼問題自然跟編碼有關了,其實很多人跟我一樣想到了對檔案編碼進行設定,並且在接資料時設定了requet的編碼,在返回的資料時設定了response的編碼一切都以為會很順利,可是這一切都是徒勞無功的,討厭的亂碼再一次出現在你眼前。在你試了N多種方法,包括JS自身的escape,unescape方法後,你發現亂碼仍然猖狂地出現在螢幕上。
其實在試過這N多方法後,很多人都沒發現,解決的方法其實很簡單,而且其答案就在我們之前處理的JSP亂碼之中。讓我們先看一下AJAX的經典請求代碼
最後別忘了在返回資料時也設定上:
xmlhttp.open( "post", url, async );
xmlhttp.setRequestHeader( "Content-Type", "text/html" );
xmlhttp.send( params );
通過前面的說明,不知道你現在看出端倪了沒有。不知道是受了網上教程的影響還是其它方面影響,setRequestHeader並是萬年不變的,也沒人想過去改它,而問題就正好出在這個地方。回想一個JSP頁面內容的編碼設定,其中有這麼一節:
contentType="text/html; charset=UTF-8"
現在知道問題了吧,所以我們要把第二句代碼改為:
xmlhttp.setRequestHeader( "Content-Type", "text/html;charset=UTF-8" );
response.setContentType( "text/xml" );
response.setCharacterEncoding( "UTF-8" );
是不是很簡單,一點都不麻煩呢?
如果要問為什麼的話,其實我們可以把xmlhttp看成是一個臨時頁面,它由瀏覽器動態產生,主要作用是在後台獲得請求的資料(可以看成是一個進階的iframe)。所以對於普通版面設定的編碼,對它也要同樣設定。而在servlet中返回資料為什麼要設定contentType和encoding其道理也是一樣的。眾所周知,jsp的最後形態就是servlet,而jsp頁首設定的那個內容其實也就是讓產生的servlet中產生這麼兩句話:
response.setContentType( "text/html" );
response.setCharacterEncoding( "UTF-8" );
而pageEncoding則是跟jvm說明了這個頁面的內容要使用什麼編碼儲存(這跟之後產生的CLASS有關係)。所以在servlet設定response的編碼也是理所當然的了。
方法四(很保險,但代碼量很大,是個不錯的選擇.)
在發送ajax請求之前,對參數escape()兩次( 例:name=escape(escape("張三")); ),然後再發送請求到伺服器,伺服器接收參數後,對參數unescape(),就可以得到正確的參數( 例:String name=unescape(request.getParameter("name")); ).
附java版的unescape實現
public static String unescape (String src)
...{
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length());
int lastPos=0,pos=0;
char ch;
while (lastPos<src.length())
...{
pos = src.indexOf("%",lastPos);
if (pos == lastPos)
...{
if (src.charAt(pos+1)==‘u‘)
...{
ch = (char)Integer.parseInt(src.substring(pos+2,pos+6),16);
tmp.append(ch);
lastPos = pos+6;
}
else
...{
ch = (char)Integer.parseInt(src.substring(pos+1,pos+3),16);
tmp.append(ch);
lastPos = pos+3;
}
}
else
...{
if (pos == -1)
...{
tmp.append(src.substring(lastPos));
lastPos=src.length();
}
else
...{
tmp.append(src.substring(lastPos,pos));
lastPos=pos;
}
}
}
return tmp.toString();
}
附:prototype ajax亂碼解決方案(已經過測試可行)
prototype對傳遞的參數都進行了編碼轉換工作,每個傳遞值通過encodeURIComponent 進行了處理.編碼會被轉換成utf-8,在後台擷取request時,應該統一使用request.setCharacterEncoding("UTF-8")對request設定編碼,而不必管頁面的編碼格式是什麼.如果使用post方法進行傳遞資料,則會自動執行:
request.setHeader(‘Content-type‘,‘application/x-www-form-urlencoded‘).確保傳遞資料編碼格式的正確.