解决SWFUpload在Chrome、Firefox浏览器下session找不到的问题
SWFUpload是一個(gè)非常不錯(cuò)的異步上傳組件,但是在Chrome、Firefox等瀏覽器下使用的時(shí)候會(huì)有問(wèn)題。問(wèn)題如下:為了防止跳過(guò)上傳頁(yè)面直 接向“接受SWFUpload上傳的一般處理程序”(假如是Upload.ashx)發(fā)送請(qǐng)求造成WebShell漏洞,我的系統(tǒng)中對(duì)于 Upload.ashx進(jìn)行了權(quán)限控制,只有登錄用戶才能進(jìn)行上傳。在IE下沒(méi)問(wèn)題,但是在Chrome下運(yùn)行報(bào)錯(cuò)“用戶未登錄”。
經(jīng)過(guò)搜索得知:因?yàn)镾WFUpload是靠Flash進(jìn)行上傳的,Flash在IE下會(huì)把當(dāng)前頁(yè)面的Cookie發(fā)到Upload.ashx,但是Chrome、Firefox下則不會(huì)把當(dāng)前頁(yè)面的Cookie發(fā)到Upload.ashx。因?yàn)?strong>Session是靠Cookie中保存的SessionId實(shí)現(xiàn)的,這樣由于當(dāng)前頁(yè)面的Cookie不會(huì)傳遞給Flash請(qǐng)求的Upload.ashx,因此請(qǐng)求的文件發(fā)送到Upload.ashx就是一個(gè)新的Session了,當(dāng)然這個(gè)Session就是沒(méi)有登錄的了。
解決這個(gè)問(wèn)題的思路也很簡(jiǎn)單,那就是手動(dòng)把SessionId傳遞給服務(wù)器,再服務(wù)器端讀出SessionId再加載Session。其實(shí)解決問(wèn)題的辦法 SWFUpload的Demo中已經(jīng)給出了,那就是在SWFUpload的構(gòu)造函數(shù)中設(shè)置post_params參數(shù):
swfu = new SWFUpload({ post_params: { "ASPSESSID": "<%=Session.SessionID %>" } post_params中設(shè)定的鍵值對(duì)將會(huì)以Form表單的形式傳遞到Upload.ashx,也就是SWFUpload提供了為請(qǐng)求增加自定義請(qǐng)求參數(shù)的接口。 上面的代碼把當(dāng)前頁(yè)面的SessionId寫(xiě)到ASPSESSID值中,當(dāng)用戶上傳文件后,ASPSESSID就會(huì)傳遞到服務(wù)器上了,在Global.asax的Application_BeginRequest中添加如下代碼: var Request = HttpContext.Current.Request; var Response = HttpContext.Current.Response; 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) { Response.StatusCode = 500; Response.Write("Error Initializing Session"); } ? ? ? ? 其中UpdateCookie方法的定義如下: static void UpdateCookie(string cookie_name, string cookie_value) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name); if (cookie == null) { cookie = new HttpCookie(cookie_name); //SWFUpload 的Demo中給的代碼有問(wèn)題,需要加上cookie.Expires 設(shè)置才可以 cookie.Expires = DateTime.Now.AddYears(1); ? ? ? ? ? ? ? ? HttpContext.Current.Request.Cookies.Add(cookie); } cookie.Value = cookie_value; HttpContext.Current.Request.Cookies.Set(cookie); }原理:當(dāng)用戶請(qǐng)求到達(dá)ASP.Net引擎的時(shí)候Application_BeginRequest方法首先被調(diào)用,在方法中看客戶端是否提交上來(lái)了ASPSESSID,如果有的話則把ASPSESSID的值寫(xiě)入Cookie(以"ASP.NET_SESSIONID"為Key,因?yàn)锳SP.Net中SessionId就是保存在"ASP.NET_SESSIONID"為Key的Cookie中的),Application_BeginRequest方法后就可以從Cookie中讀取到"ASP.NET_SESSIONID"的值還原出頁(yè)面的Session了。
如果網(wǎng)站中還用到了Membership的FormsAuthentication驗(yàn)證,則還需要把AUTHID也按照SessionID的方法進(jìn)行處理,這一點(diǎn)是其他講到SWFUpload這個(gè)Bug處理的文章中沒(méi)有提到的。
在SWFUpload的構(gòu)造函數(shù)中設(shè)置post_params參數(shù):
swfu = new SWFUpload({ upload_url: "/AdminHT/UploadArticleImg.ashx", post_params: { "ASPSESSID": "<%=Session.SessionID %>", "AUTHID" : "<%=Request.Cookies[FormsAuthentication.FormsCookieName].Value%>" }, 在在Global.asax的Application_BeginRequest中添加如下代碼: 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) { Response.StatusCode = 500; Response.Write("Error Initializing Forms Authentication"); }總結(jié)
以上是生活随笔為你收集整理的解决SWFUpload在Chrome、Firefox浏览器下session找不到的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python的弱引用
- 下一篇: 前端笔试练习三