ASP.NET MVC 檔案上傳使用 Uploadify 套件的注意事項
- 2011-12-25
- 16264
- 0
Uploadift 是一套基於 jQuery 和 Flash 的檔案上傳工具,提供了上傳進度以及多檔上傳的功能,畫面簡單大方是一個相當不錯的上傳套件。
雖然標題上是說針對 ASP.NET MVC 但是其實在 ASP.NET Web form 的使用方式也很像,只有接檔的方式不同和 Global 內的一個設定不相同而已。
當您參照了官網的 Documentation 後一定是可以正常的套用成功(如果你對於 jQuery 不熟的話很抱歉本篇無法教您如何套用),套用成功後在擁有檔案權限的頁面中測試使用 IE 可以發現一切是如此的完美,但當改用 Firefox 、 Chrome 測試的時候你會發現打死都無法上傳成功,這是因為瀏覽器安全設計的問題,Uploadift 是利用 Flash 來上傳檔案的,在 IE 中會很好心的將 cookie 帶出去,但是在 Firefox 、 Chrome 中認為這樣不安全,並不會帶過去,因為沒有相關的 Cookie 系統認為是不合法的使用者所以拒絕訪問而導致上傳失敗。
要排除這種問題就需要在 Global 中明確的指定傳送相關的 Cookie 出去
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 { } 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 { } } private void UpdateCookie(string cookie_name, string cookie_value) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name); if (null == cookie) { cookie = new HttpCookie(cookie_name); } cookie.Value = cookie_value; HttpContext.Current.Request.Cookies.Set(cookie); }
這段 code 從 swfupload 年代就是這樣寫的了,這樣寫是沒什麼不對,但是 demo 一直覺得明明只有後端需要上傳的頁面才需要這樣自己丟 cookie 何必全世界都跑,於是就改寫一下,增加了一些基本的判斷。
void Application_BeginRequest(object sender, EventArgs e) { //先撈出 Route Data 的資料 var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current)); object areaName = null; //判斷 屬於後台的 Area (本範例是有針對後台開一個 Area) 的情況 if (routeData != null && routeData.DataTokens.TryGetValue("area", out areaName) && (string)areaName == "Admin") { //將需要用的 Controller 都加進去 string[] controller = new string[] { "Acontroller", "Bcontroller" }; //將需要用的 Action 也都加進去 string[] action = new string[] { "AddFile", "Upload" }; //判斷屬於要跑的頁面再跑 if (controller.Contains(routeData.Values["controller"].ToString()) && action.Contains(routeData.Values["action"].ToString())) { 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 { } 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 { } } } } private void UpdateCookie(string cookie_name, string cookie_value) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name); if (null == cookie) { cookie = new HttpCookie(cookie_name); } cookie.Value = cookie_value; HttpContext.Current.Request.Cookies.Set(cookie); }
增加判斷頁面的功能再丟感覺好像就是比較安全一點,沒必要的東西還是跑的好
回應討論