傳智播客:ajax學習筆記---解決瀏覽器緩存和中文亂碼 - habernate的日誌 -...

傳智播客:ajax學習筆記---解決瀏覽器緩存和中文亂碼

java 2009-04-09 14:24:20 閱讀5 評論0 字型大小:大中小訂閱

Ajax中瀏覽器緩存導致的問題問題描述:當XMLHttpRequest對象利用open方法向伺服器發送請求的時候,當一次請求成功以後,頁面會把請求到的值存放在頁面緩存中,當你第二次發送同樣的請求的時候。瀏覽器不會再去伺服器重新取值,而是自動去頁面緩存中查找。這樣導致瀏覽器獲得的永遠是哪個第一次請求時獲得的值而無法從瀏覽器中獲得新的值.例如cachexmlhttp.open("GET","cache",true);但瀏覽器第二次請求cache的時候,由於這次請求和上次請求的對象是一樣的,而且瀏覽器緩存中已經保存了上次請求的值,所以就不再去請求cache,而是直接從緩存中獲取上次保存的值解決方法在每次向伺服器發送請求的時候,在url裡面拼上一個當前時間的時間戳,這樣瀏覽器就會認為每次請求都不一樣,就會去向伺服器發送請求了var url="cache";//為url添加上時間戳if(url.indexof("?")>=0){ //如果請求的url原來就有參數 url=url+"&t="+(new Date()).valueOf();} else{ //如果請求的url原來沒有參數 url=url+"?t="+(new Date()).valueOf();}cachexmlhttp.open("GET",url,true);關於中文亂碼問題Ajax中文亂碼問題分為兩種,一種是伺服器端返回數據是中文,一種是頁面發送到伺服器的數據是中文。先討論伺服器端返回數據是中文的情況。對於IE6以上的瀏覽器,這個問題的解決辦法就是XMLHttpRequest對象在頁面端定義的Charset和伺服器端的http響應頭的Content-Type中定義的Charset保持一致就不會有問題。但是對於IE6,所有的事情就變態起來了。即使按照上面的原則同樣解決不了問題。這個時候有兩個解決問題的辦法方法1這個方法很詭異,因為它和前面論述的東西是向矛盾的,在IE6中定義的XMLHttpRequest對象在頁面端定義的Charset和伺服器端的http響應頭的Content-Type中定義的Charset都是GB2312的時候,同樣會出現亂碼。這個時候,把伺服器端的http響應頭的Content-Type中定義的Charset設置成utf-8就可以解決問題。方法2這個是推薦的方法,在IE6中定義XMLHttpRequest對象的時候,只使用MSXML2.XMLHTTP和Miscrosoft.XMLHTTP兩個版本的Activex控制項來創建就可以解決這個問題,下面是代碼這是微軟推薦的做法。所以通常就這麼用了var activexName = ["MSXML2.XMLHTTP","Miscrosoft.XMLHTTP"];for (var i = 0; i <activexName.length; i++) {try{xmlhttp = new ActiveXObject(activexName);break;} catch(e) {}}對於頁面端發送到伺服器中文導致的亂碼問題當頁面段和伺服器端使用的編碼方式都是GB2312的時候解決辦法是在頁面端獲取需要發送的字元串,進行兩次編碼再傳送到伺服器,代碼如下var userName = document.getElementById("UserName").value;//但頁面請求參數出現中文,在頁面端取得參數後進行兩次編碼。//然後在伺服器端對編碼後的內容進行一次解碼,就可以解決這個問題。userName = encodeURI(encodeURI(userName));//在伺服器端,對接收到的數據進行一次解碼操作就可以解決問題具體操作如下String old = request.getParameter("name");//對經過頁面端兩次編碼的參數進行一次解碼。避免了中文亂碼問題.String name = URLDecoder.decode(old,"utf-8");這樣問題就得以解決其中具體的原理分析如下,假設頁面端輸入的中文是一個「中」,按照下面步驟進行解碼1.第一次encodeURI,按照utf-8方式獲取位元組數組變成[-28,-72-83],對位元組碼數組進行遍歷,把每個位元組轉化成對應的16進位數,這樣就變成了[E4,B8,AD],最後變成[%E4,%B8,%AD]2.第二次encodeURI,把數組最後變成[%25E4,%25B8,%25AD]然後就把處理後的數據[%25E4,%25B8,%25AD]發往伺服器端當應用伺服器調用getParameter方法,getParameter方法會去嚮應用伺服器請求參數應用伺服器最初獲得的就是發送來的[%25E4,%25B8,%25AD],應用伺服器會對這個數據進行URLdecode操作,URldecode操作和encodeURL操作是相反的操作,處理結果就是[%E4,%B8,%AD],並把這個值返回給getParameter方法然後再在servlet中調用URLDecoder.decode(old,"utf-8")就可以把數據還原成最初頁面發送過來的中文「中」了。這麼在頁面兩次編碼encodeURI(encodeURI(userName));再到伺服器用utf8方式解碼一次URLDecoder.decode(old,"utf-8");這麼麻煩的原因是:應用伺服器自身總會進行一次URLdecode操作,而不同版本的應用伺服器解碼所用的編碼版本又都不一樣,如果把數據直接發送到應用伺服器,結果不同版本的應用伺服器解碼得到的結果是不可預料的,必然得到的是亂碼。而這樣在頁面段兩次編碼後產生的[%25E4,%25B8,%25AD]無論結果什麼版本的應用伺服器解碼,產生的結果都是[%E4,%B8,%AD]。這樣在servlet那裡進行一次URLDecoder.decode(old,"utf-8");就可以得到正確的結果。(再具體的東西目前還沒有查到詳細資料,等搞清楚再解釋)
推薦閱讀:

TAG:學習 | 筆記 | 亂碼 | 緩存 | 瀏覽器 | 中文亂碼 | 傳智播客 | 瀏覽器緩存 | 日誌 | 中文 | 播客 |