關於 SWFUpload 在firefox (ff,火狐)下,報錯 302,session,cookie
最近在處理多檔案上傳問題,一直以來都是用jquery的MultiFile.js外掛,但是由於該外掛不能顯示進度條的緣故,而專案實際上對進度條必不可少
再加上實在是不願意花時間去寫檔案上傳進度,只得在網上找到了swfupload用flash上傳檔案的外掛,在IE下上傳多檔案十分順利,但是在火狐下
卻總是報302錯誤,通過千百度,驀然回首到谷歌折騰了番,才瞭解了原因,謹以此篇小計下來,畢竟上傳帶進度條的功能實在是太常見了,先收
著。
因為SWFUpload是靠Flash進行上傳的,Flash在IE下會把當前頁面的Cookie發到Upload.aspx,但是Chrome、Firefox下則不會把當前頁面的Cookie發到Upload.aspx。
解決這個問題的思路也很簡單,那就是手動把SessionId傳遞給伺服器,再伺服器端讀出SessionId再載入Session。其實解決問題的辦法SWFUpload的Demo中已經給出了,那就是在SWFUpload的建構函式中設定post_params引數:
swfu = new SWFUpload({ // Backend Settings upload_url: "/Upload.aspx", post_params: { "ASPSESSID": "<%=Session.SessionID %>"},
post_params中設定的鍵值對將會以Form表單的形式傳遞到Upload.aspx,也就是SWFUpload提供了為請求增加自定義請求引數的介面。
如果網站中還用到了Membership的FormsAuthentication驗證,則還需要把AUTHID也按照SessionID的方法進行處理
swfu = new SWFUpload({ // Backend Settings upload_url: "/Upload.ashx", post_params: { "ASPSESSID": "<%=Session.SessionID %>"}, "AUTHID" : "<%=Request.Cookies[FormsAuthentication.FormsCookieName].Value%>",
上面的程式碼把當前頁面的SessionId寫到ASPSESSID值中,當用戶上傳檔案後,ASPSESSID就會傳遞到伺服器上了,在Global.asax的Application_BeginRequest中新增如下程式碼:
protected void Application_BeginRequest(object sender, EventArgs e)
{
try
{
string session_param_name = "ASPSESSID";
string session_cookie_name = "ASP.NET_SESSIONID";
if (HttpContext.Current.Request.Form[session_param_name] != null)
{
UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
}
else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
{
UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
}
}
catch (Exception)
{
}
try
{
string auth_param_name = "AUTHID";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
if (HttpContext.Current.Request.Form[auth_param_name] != null)
{
UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
}
else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
{
UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
}
}
catch (Exception)
{
}
}
void UpdateCookie(string cookie_name, string cookie_value)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (cookie == null)
{
HttpCookie cookie1 = new HttpCookie(cookie_name, cookie_value);
Response.Cookies.Add(cookie1);
}
else
{
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
}
}
原理:當用戶請求到達ASP.Net引擎的時候Application_BeginRequest方法首先被呼叫,在方法中看客戶端是否提交上來了ASPSESSID,如果有的話則把ASPSESSID的值寫入Cookie(以"ASP.NET_SESSIONID"為Key,因為ASP.Net中SessionId就是儲存在"ASP.NET_SESSIONID"為Key的Cookie中的),Application_BeginRequest方法後就可以從Cookie中讀取到"ASP.NET_SESSIONID"的值還原出頁面的Session了。
如果網站是使用Windows方式驗證的,post_params:{
ASPSESSID: "<%=Session.SessionID %>",這樣便可,不需要在Application_BeginRequest寫任何方法。
相關閱讀