demoshop

demo, trying to be the best_

官方網站
http://www.uploadify.com/

Uploadift 是一套基於 jQuery 和 Flash 的檔案上傳工具,提供了上傳進度以及多檔上傳的功能,畫面簡單大方是一個相當不錯的上傳套件。

注意事項雖然標題上是說針對 ASP.NET MVC 但是其實在 ASP.NET Web form 的使用方式也很像,只有接檔的方式不同和 Global 內的一個設定不相同而已。

demo廢言當您參照了官網的 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);
}

增加判斷頁面的功能再丟感覺好像就是比較安全一點,沒必要的東西還是跑的好

回應討論