jquery.uploadify文件上傳組件


1、jquery.uploadify簡介

    在ASP.NET中上傳的控件有很多,比如.NET自帶的FileUpload,以及SWFUpload,Uploadify等等,尤其后面兩個控件的用戶體驗比較好,無刷新,帶上傳進度等等。在最近的短信平台開發中,使用Uploadify進行文件上傳。

    Uploadify官網地址是:http://www.uploadify.com/ 可滿足項目開發需求。

image

    下載地址:http://www.uploadify.com/wp-content/uploads/files/uploadify.zip 版本信息如下:

image

    解壓之后,目錄結構如下(不在詳細解釋):

image

2、使用流程

    下載的程序是PHP示例,由於項目使用的是asp.net mvc,使用uploadify可分以下步驟:

  • (1)加入uploadify js類庫(把uploadify相關js類庫引用到項目的相關位置,比如放到scripts目錄)
  • (2)對uploadify二次進行封裝,滿足項目調用
  • (3)編寫文件上傳處理方法
  • (4)頁面引用相關類庫並編寫上傳腳本

2.1 對uploadify二次進行封裝

    針對uploadify調用進行js類庫封裝,滿足項目使用:

    //轉換成key=value&key=value格式
    tx.toParam = function (dto) {
        return jQuery.param(dto);
    }
    //設置上傳文件
    tx.uploadify = function (divId, options, action) {
        if (options == undefined && action == undefined) {
            $('#' + divId).uploadify("upload");
            return;
        }
        if (options == undefined) {
            abp.message.warn("請輸入參數配置");
            return;
        }
        var fileexts = options.fileexts;
        if (fileexts == undefined || fileexts.length <= 0) {
            abp.message.warn("要選擇文件的擴展名不能為空");
            return;
        }
        $('#' + divId).uploadify({
            uploader: '/files/upload?r=' + Math.random()
                + "&fileexts=" + encodeURIComponent(fileexts)
                + "&" + (options !== undefined ? tx.toParam(options.params) : ""),  // 服務器端處理地址
            swf: '/Scripts/uploadify/uploadify.swf',    // 上傳使用的 Flash

            width: 60,                          // 按鈕的寬度
            height: 23,                         // 按鈕的高度
            buttonText: "選擇文件",                 // 按鈕上的文字
            buttonCursor: 'hand',                // 按鈕的鼠標圖標

            fileObjName: 'Filedata',            // 上傳參數名稱
            fileTypeExts: fileexts,             // 擴展名
            fileTypeDesc: "請選擇文件",     // 文件說明
            fileDesc: '不超過200M的',
            sizeLimit: 204800000,  //允許上傳的文件大小(kb)  此為2M
            auto: false,                // 選擇之后,自動開始上傳
            multi: true,               // 是否支持同時上傳多個文件
            queueSizeLimit: 1,          // 允許多文件上傳的時候,同時上傳文件的個數
            onSelectOnce: function (event, data) { //在單文件或多文件上傳時,選擇文件時觸發
                //event 事件對象(the event object)
                //data 選擇的操作信息
                //data.filesSelected 選擇文件操作中選中的文件數量
            },
            onUploadStart: function (file) {
                //file:將要上載的文件對象
                ShowBusy();
            },
            onUploadComplete: function (file) {
                //file:上傳或返回一個錯誤的文件對象。
            },
            onUploadSuccess: function (file, data, response) {
                //file:成功上傳的文件對象
                //data:服務器端腳本返回的數據(任何由文件響應的任何東西)
                //response:服務器返回的響應是否真的成功或錯誤,如果沒有響應。如果返回false,這successtimeout期權到期后的反應真是假設。
                if (action !== undefined) {
                    action(JSON.parse(data));
                }
                ClearBusy();
            },
            onUploadError: function (file, errorCode, errorMsg, errorString) {
                //file:上傳的文件對象
                //errorCode:返回的錯誤代碼
                //errorMsg:返回的錯誤消息
                //errorString:包含錯誤的所有細節的可讀的錯誤信息
                if (action !== undefined) {
                    if (action !== undefined) {
                        action({
                            result: errorCode,
                            message: errorMsg,
                            filename: "",
                            fileext: ""
                        });
                    }
                }
                ClearBusy();
            }
        });
    }

2.2 文件上傳處理

    使用MVC特性,要登錄之后才能進行文件上傳:

using System;
using System.IO;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace TxSms.Web.Controllers
{
    /// <summary>
    /// 文件上傳管理
    /// </summary>
    [Authorize]
    public class FilesController : TxSmsControllerBase
    {
        private static string jsonResult = "{0}\"result\":{1},\"message\":\"{2}\",\"filename\":\"{3}\",\"fileext\":\"{4}\"{5}";

        /// <summary>
        /// 文件上傳頁面
        /// </summary>
        /// <returns></returns>
        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 上傳文件
        /// </summary>
        /// <param name="filedata"></param>
        /// <returns></returns>
        [Authorize]
        public ActionResult Upload(HttpPostedFileBase filedata)
        {
            // 如果沒有上傳文件
            if (filedata == null || filedata.FileName.IsNullOrEmpty() || filedata.ContentLength == 0)
            {
                return new JsonStringResult(string.Format(jsonResult, "{", -1, "", "", "", "}"));
            }
            string parmPath = Request.QueryString["path"];
            string parmGetzipfile = Request.QueryString["getzipfile"];
            if (parmGetzipfile.IsNullOrEmpty())
            {
                parmGetzipfile = "0";
            }
            // 保存到 ~/uploads 文件夾中,名稱不變
            string time = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            string fileext = Path.GetExtension(filedata.FileName);
            string filename = time + fileext;

            string virtualPath = parmPath.IsNullOrEmpty()
                 ? $"~/uploads/"
                 : $"~/uploads/{parmPath}/";
            string actualPath = Server.MapPath(virtualPath);
            if (!Directory.Exists(actualPath))
            {
                Directory.CreateDirectory(Server.MapPath(virtualPath));
            }
            // 文件系統不能使用虛擬路徑
            var destFile = virtualPath + filename;
            string path = Server.MapPath(destFile);
            filedata.SaveAs(path);

            bool iszip = fileext != null && (fileext.Equals(".zip", StringComparison.OrdinalIgnoreCase) && parmGetzipfile.Equals("1"));
            if (iszip)
            {
                var virtualPathZip = virtualPath + time + "/";
                string actualPathZip = Server.MapPath(virtualPathZip);
                if (!Directory.Exists(actualPathZip))
                {
                    Directory.CreateDirectory(actualPathZip);
                }
                destFile = fileext = "";
                //第一步驟,解壓
                TxSmsZipHelper.UnZipFile(path, actualPathZip);
                //第二步驟,獲取excel文件,如果沒有獲取到,則拋出異常
                //獲得目錄信息
                var dir = new DirectoryInfo(actualPathZip);
                //獲得目錄文件列表
                var files = dir.GetFiles();
                foreach (FileInfo fileName in files)
                {
                    //var ext = Path.GetExtension(fileName.Name).ToLower();
                    //if (ext == ".xls" || ext == ".xlsx")
                    //{
                    //    destFile = Path.Combine(fileName.DirectoryName, fileName.Name);
                    //    break;
                    //}
                    destFile = virtualPathZip + fileName.Name;
                    fileext = Path.GetExtension(fileName.Name);
                    break;
                }
            }

            return new JsonStringResult(string.Format(jsonResult, "{", 0, "上傳成功", destFile, fileext.ToLower(), "}"));
        }

        public class JsonStringResult : ContentResult
        {
            public JsonStringResult(string json)
            {
                Content = json;
                ContentType = "application/json";
            }
        }
    }
}

    文件上傳路徑:/files/upload

2.3 頁面調用

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
<link href="/Content/themes/base/uploadify/uploadify.css" rel="stylesheet"/>

<script src="/Scripts/jquery-2.1.4.min.js"></script>
<script src="/Scripts/uploadify/jquery.uploadify.min.js"></script>

    <script type="text/javascript">
        $(function () {
            var ASPSESSID = '3iupfg2udk4m5hyzfj5ydlso';
            var auth = '';

            //初始化
            tx.uploadify('uploadify'
                ,
                { //參數配置
                    fileexts: "*.jpg;*.png;*.zip", //要選擇文件的擴展名,多個用;分割
                    //formData: { ASPSESSID: ASPSESSID, AUTHID: auth },
                    params: { //參數
                        path: 'files',//上傳路徑,允許為空
                        getzipfile: 1 //解壓zip文件,並獲取文件 0:不解壓獲取,1:解壓獲取
                    }
                }
                , function (data) { //回調函數
                    //data.result:0 表示成功,其他表示錯誤
                    //data.message:信息
                    //data.filename:文件名稱
                    //data.fileext:文件擴展
                    console.log(data.result);
                    console.log(data.message);
                    console.log(data.filename);
                    console.log(data.fileext);
                });
            $("#btnUpload").click(function () {
                tx.uploadify('uploadify'); //開始上傳
            });
        });
    </script>
</head>
<body>
    <div style="margin: 40px;">
        <div id="uploadify"></div>
        <button id="btnUpload">開始上傳</button>
    </div>
</body>
</html>

    允許程序,界面如下:

image

    選擇文件—>開始上傳:

image

image

    ok,到此已經完成。

3、http 302解決方案

    很懷疑二八原則,很快就出現了。同事用firefox進行測試,遇到如下提示:

image

    查找大量資料,發下是Upload方法認證的問題,去掉[Authorize]屬性標簽即可,代碼修改如下:

using System;
using System.IO;
using System.Web;
using System.Web.Mvc;

namespace TxSms.Web.Controllers
{
    /// <summary>
    /// 文件上傳管理
    /// </summary>
    //[Authorize]
    public class FilesController : TxSmsControllerBase
    {
        private static string jsonResult = "{0}\"result\":{1},\"message\":\"{2}\",\"filename\":\"{3}\",\"fileext\":\"{4}\"{5}";

        /// <summary>
        /// 文件上傳頁面
        /// </summary>
        /// <returns></returns>
        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 上傳文件
        /// </summary>
        /// <param name="filedata"></param>
        /// <returns></returns>
        //[Authorize]
        public ActionResult Upload(HttpPostedFileBase filedata)
        {
            //加入認證信息
            if (this.LoginUser == null)
            {
                return new JsonStringResult(string.Format(jsonResult, "{", -1, "抱歉,未登錄,不允許上傳", "", "", "}"));
            }
            // 如果沒有上傳文件
            if (filedata == null || filedata.FileName.IsNullOrEmpty() || filedata.ContentLength == 0)
            {
                return new JsonStringResult(string.Format(jsonResult, "{", -2, "無上傳文件", "", "", "}"));
            }
            string parmPath = Request.QueryString["path"];
            string parmGetzipfile = Request.QueryString["getzipfile"];
            if (parmGetzipfile.IsNullOrEmpty())
            {
                parmGetzipfile = "0";
            }
            // 保存到 ~/uploads 文件夾中,名稱不變
            string time = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            string fileext = Path.GetExtension(filedata.FileName);
            string filename = time + fileext;

            string virtualPath = parmPath.IsNullOrEmpty()
                 ? $"~/uploads/"
                 : $"~/uploads/{parmPath}/";
            string actualPath = Server.MapPath(virtualPath);
            if (!Directory.Exists(actualPath))
            {
                Directory.CreateDirectory(Server.MapPath(virtualPath));
            }
            // 文件系統不能使用虛擬路徑
            var destFile = virtualPath + filename;
            string path = Server.MapPath(destFile);
            filedata.SaveAs(path);

            bool iszip = fileext != null && (fileext.Equals(".zip", StringComparison.OrdinalIgnoreCase) && parmGetzipfile.Equals("1"));
            if (iszip)
            {
                var virtualPathZip = virtualPath + time + "/";
                string actualPathZip = Server.MapPath(virtualPathZip);
                if (!Directory.Exists(actualPathZip))
                {
                    Directory.CreateDirectory(actualPathZip);
                }
                destFile = fileext = "";
                //第一步驟,解壓
                TxSmsZipHelper.UnZipFile(path, actualPathZip);
                //第二步驟,獲取excel文件,如果沒有獲取到,則拋出異常
                //獲得目錄信息
                var dir = new DirectoryInfo(actualPathZip);
                //獲得目錄文件列表
                var files = dir.GetFiles();
                foreach (FileInfo fileName in files)
                {
                    //var ext = Path.GetExtension(fileName.Name).ToLower();
                    //if (ext == ".xls" || ext == ".xlsx")
                    //{
                    //    destFile = Path.Combine(fileName.DirectoryName, fileName.Name);
                    //    break;
                    //}
                    destFile = virtualPathZip + fileName.Name;
                    fileext = Path.GetExtension(fileName.Name);
                    break;
                }
            }

            return new JsonStringResult(string.Format(jsonResult, "{", 0, "上傳成功", destFile, fileext.ToLower(), "}"));
        }

        public class JsonStringResult : ContentResult
        {
            public JsonStringResult(string json)
            {
                Content = json;
                ContentType = "application/json";
            }
        }
    }
}

    再次用firefox測試如下:

image

image

4、注意事項

    1、封裝的js類庫適合單文件上傳

    2、upload里面的登錄認證是通過判斷當前賬號信息是否為null

    3、本項目使用的abp框架,有興趣的可以去了解下:http://www.aspnetboilerplate.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM