解決兩種情況下的用戶訪問(wèn)超時(shí)。
a)普通http請(qǐng)求的session超時(shí)。
b)異步http請(qǐng)求的session超時(shí),使用ext后大部分的界面刷新都是異步的ajax請(qǐng)求。
不管是那種類型的http請(qǐng)求總是可以由一個(gè)過(guò)濾器來(lái)捕捉。
分類:普通http請(qǐng)求的header參數(shù)中沒(méi)有x-requested-with:XMLHttpRequest頭信息,而異步的有。
其實(shí)對(duì)于常見(jiàn)的ajax框架,header中還有標(biāo)示自己身份的header信息。
對(duì)于普通的http請(qǐng)求,發(fā)現(xiàn)session超時(shí)后直接重定向到一個(gè)超時(shí)頁(yè)面,顯示訪問(wèn)超時(shí)。
對(duì)于異步http請(qǐng)求,發(fā)現(xiàn)session超時(shí)后則向請(qǐng)求的response中寫(xiě)入特定的超時(shí)頭信息,客戶端ajax對(duì)象檢測(cè)
頭信息,發(fā)現(xiàn)有超時(shí)狀態(tài)標(biāo)志后調(diào)用顯示超時(shí)信息的javascript方法,提示用戶訪問(wèn)超時(shí)。
服務(wù)器端session超時(shí)后在過(guò)濾器中為response添加新的頭信息,標(biāo)記該請(qǐng)求超時(shí):
if(r.getHeader("x-requested-with")!=null
&& r.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
response.setHeader("sessionstatus","timeout");
}
使用Ext.Ajaxt對(duì)象完成異步請(qǐng)求的交互,Ext.Ajax是單實(shí)例對(duì)象(非常重要,全局單一Ext.Ajax實(shí)例!)。
注冊(cè)Ext.Ajax的requestcomplete事件,每個(gè)ajax請(qǐng)求成功后首先響應(yīng)該事件。在該事件的回調(diào)函數(shù)里面判斷
訪問(wèn)請(qǐng)求是否超時(shí)。使用Ext.Ajax對(duì)象的好處是,只需要引入一個(gè)包含了幾行超時(shí)處理代碼的js文件,就可以
為當(dāng)前應(yīng)用增加超時(shí)處理功能,原有代碼不需要做任何修改。
使用Ext.Ajaxt對(duì)象完成異步請(qǐng)求交互,假如checkUserSessionStatus是你的回調(diào)方法,每個(gè)頁(yè)面引用:
Ext.Ajax.on('requestcomplete',checkUserSessionStatus, this);
function checkUserSessionStatus(conn,response,options){
//Ext重新封裝了response對(duì)象
if(typeof response.getResponseHeader.sessionstatus != 'undefined'){
//發(fā)現(xiàn)請(qǐng)求超時(shí),退出處理代碼...
}
}
可以利用的幾個(gè)特性:
a)所有的ajax請(qǐng)求均帶有x-requested-with:XMLHttpRequest頭信息
b)Ext.Ajax是單實(shí)例對(duì)象(非常重要,全局單一Ext.Ajax實(shí)例!)
c)注冊(cè)Ext.Ajax的requestcomplete事件,每個(gè)ajax請(qǐng)求成功后首先響應(yīng)該事件(概念類似spring的aop攔截)。
jquery提供了幾個(gè)全局事件可以用來(lái)處理session過(guò)期請(qǐng)求,如當(dāng)ajax請(qǐng)求開(kāi)始時(shí)會(huì)觸發(fā)ajaxStart()方法的回調(diào)函數(shù);
當(dāng)ajax請(qǐng)求結(jié)束時(shí),會(huì)觸發(fā)ajaxStop()方法的回調(diào)函數(shù)。這些方法都是全局的方法,因此無(wú)論創(chuàng)建它們的代碼位于何處,
只要有ajax請(qǐng)求發(fā)生時(shí),都會(huì)觸發(fā)它們。類似的事件還有:ajaxComplete(),ajaxError(),ajaxSend(),ajaxSuccess()等。
如果使某個(gè)ajax請(qǐng)求不受全局方法的影響,那么可以在使用$.ajax()方法時(shí),將參數(shù)中的global設(shè)置為false,jquery代碼如下:
$.ajax({
url:"test.html",
global:false//不觸發(fā)全局ajax事件
})
對(duì)于其他的ajax框架,解決用戶訪問(wèn)請(qǐng)求超時(shí)這個(gè)問(wèn)題的思路是類似的。
在這里推薦一個(gè)很實(shí)用的Js方法:
function getRootWin(){
var win = window;
while (win != win.parent){
win = win.parent;
}
return win;
}
通過(guò)該方法,可以在一個(gè)任意深度的iframe中調(diào)用父iframe中的方法。具體到這里就是無(wú)論哪一個(gè)iframe中的用戶訪
問(wèn)請(qǐng)求超時(shí),都可以通過(guò)該方法調(diào)用最外層iframe中的退出方法,這樣便為用戶提供了一個(gè)統(tǒng)一的訪問(wèn)超時(shí)退出的UI
呈現(xiàn)。