文件上傳的幾種方法——plupload篇

其實用這個組件以前,原先是想接着用webuploader的,畢竟用過了,比較熟悉,並且也很好用。然鵝,由於是要上傳到七牛,遇到了跨域的問題,嘗試過網上的幾種解決方法,都沒用。只好用七牛文檔裏面的plupload,hhhhhh,官方文檔推薦的,總歸不會有什麼問題~其實這篇文章咧,不是純粹的怎麼用plupload,會有一部分邏輯處理(腦子實在很差用,怕忘記了到時候還要從新想一遍邏輯,想一想仍是記下來吧)javascript

https://developer.qiniu.com/k... 這個是七牛官網Javascript SDK的文檔,項目過程當中遇到的問題,也都是直接翻文檔。由於用的plupload,有些參數七牛的文檔沒那麼詳細,http://www.cnblogs.com/2050/p... 這個連接是從七牛官網跳轉過去的~很詳細。因爲官方文檔已經寫得很詳細,這邊就不過多的介紹參數、方法啥的,把項目中有注意到的參數、遇到的問題及解決方法整理一下。html

大體過程是這樣的前端

  1. 能夠去github上面下載SDK源碼,也能夠經過NPM或者Bower安裝。(官網有安裝教程)html5

  2. 把js文件引入,我是用plupload.full.min.js、moxie.min.js、qiniu.min.js、Moxie.swfjava

  3. 由於是前端的關係,七牛的帳號密碼,包括token、下載資源用的bucket域名等這些是後臺的小夥伴提供的,在用到圖片上傳以前,先經過後臺小夥伴提供的接口請求七牛的tokenjquery

  4. 接下去就能夠寫代碼啦(貼完代碼發現本身寫了好一些邏輯處理,趕忙跳上來先把一些能夠分享的東西寫到上面來)git

auto_start:是否自動上傳,通常單圖片上傳的話,我會設會true,而且在FileUploaded事件中獲取到圖片的地址後,在頁面中顯示預覽。多圖片的話,就設爲false,等到提交時,調用start方法一塊兒上傳,好比imgUploader.start(),上傳的時間會久一點,可是不會有不少無用的圖片佔用存儲空間(這也是項目中的需求啦)github

在項目中,有多個地方用到單圖片上傳,我就把上傳封裝在一個方法中,這樣可能會想要重寫某個事件,能夠經過綁定該事件實現,好比imgUploader.bind('FileUploaded', function (up, file, info) {));web

在多圖片上傳的過程當中,常常會出現http error.的錯誤,可是單圖片歷來不會。一開始覺得是一會兒上傳太多張的緣故,就把auto_start改成true,然鵝仍是會報錯。。。
我抱着天無絕人之路盯着chrome開發者工具中的network看了很久,發現報http error的IP都是同一個!!!我就打開qiniu.js拿了上傳域名中的http://up.qiniu.com去解析,發現真有那個IP,再而後,我把http://up-z2.qiniu.com所有換成http://upload-z2.qiniu.com,就能夠了~因爲不知道爲何會這樣,因此只能說若是有遇到跟我同樣的問題能夠試試看,不保證有用~hhhhhajax

還有一個問題昂,順便提一下,項目中,我有使用requirejs,由於plupload和qiniu.js這些不是按AMD或者CMD啥的規範組織的,作了一下處理,大約長這樣

shim: {
    'moxie': {
        deps: ['jquery']
    },
    'plupload': {
        exports: 'plupload'
    },
    'Qiniu': {
        deps: ['plupload'],
        exports: 'Qiniu'
    }
}

單圖片上傳沒啥好說的,直接上多圖片上傳的代碼

// 界面的上傳按鈕和圖片列表
<div id="uploader">
    <div id="uploaderShopContainer">
    <!--用來存放item-->
    <div id="fileList" class="uploader-list"></div>
    <a class="btn-normal blue-btn" id="uploadShopPic" href="#" >
        <span>上傳圖片</span>
    </a>
    </div>
</div>
<ul id="shopPicList" class="pic-cont"></ul>
// js
var imgUploader, // 上傳對象
    uploadStoreImgUrl = [], // 當前圖片列表(在編輯的狀況下,圖片列表可能不會爲空,這個變量也是做爲表單上傳中圖片列表的參數)
    uploadSuccessList = [],  // 圖片上傳成功後返回的列表
    fileNameList = []; // 添加圖片後的隊列
$.ajax({
    url: 'api/qiniu/token', // 獲取七牛token的url(這個是後臺給的)
    method: 'GET',
    success: function (data) {
        imgUploader = Qiniu.uploader({
            runtimes: 'html5,flash,html4', // 上傳模式,依次退化
            browse_button: 'uploadShopPic', // 上傳選擇的點選按鈕,必需
            container: 'uploaderShopContainer', // 上傳區域DOM ID,默認是browser_button的父元素
            flash_swf_url: '../vendor/js/plupload/Moxie.swf',
            dragdrop: false,
            auto_start: false, // 選擇文件後自動上傳,若關閉須要本身綁定事件觸發上傳
            multi_selection: true,
            unique_names: true,
            max_retries: 0,  // 上傳失敗最大重試次數
            save_key: false,
            uptoken:data.token, // 這個就是請求返回的七牛token啦
            uptoken_url:'api/qiniu/token',
            domain: '<Your bucket domain>', // bucket域名,下載資源時用到,必需
            chunk_size: '4mb',                  // 分塊上傳時,每塊的體積
            resize:true,
            filters : { // 限制上傳的文件類型、大小等
                mime_types: [{title : "Image files", extensions:"jpg,gif,png"}]
                },
           init: {
               'FilesAdded': function(up, files) {
               // 由於需求中這個圖片列表最多隻能有10張,判斷是否超過,超過的則移除
                var count = files.length + uploadStoreImgUrl.length + fileNameList.length;
                if (files.length > 10 && (uploadStoreImgUrl.length+fileNameList.length) == 0) {
                    var addLength = files.length;
                    for (var i = addLength - 1; i > addLength-1; i--) {
                        imgUploader.removeFile(files[i].id);
                        files.splice(i, 1);
                    }
                }
                if (count > 10) {
                    var addFile = files.length - (count - 10) - 1, tempLength = files.length;
                    for (var m = tempLength-1; m > addFile; m--) {
                        imgUploader.removeFile(files[m].id);
                        files.splice(m, 1);
                    }
                }
                plupload.each(files, function(file) {

                    // 文件添加進隊列後,處理相關的事情
                    // 上傳前預覽
                    var isAdd = true;
                    // 先判斷要上傳的圖片是否重複
                    for (var i = 0; i < fileNameList.length; i++) {
                        if (file.name == fileNameList[i]) {
                            isAdd = false;
                            return false;
                        }
                    }
                    // 若是不是重複的,則添加到上傳隊列,而且在頁面預覽
                    if (isAdd) {
                        fileNameList.push(file.name);
                        var preloader = new mOxie.Image();
                        preloader.onload = function() {
                        preloader.downsize( 100, 100);
                        var imgItem = '<img id="'+file.id+'" name="'+file.name+'" src="'+preloader.getAsDataURL()+'" class="pic-thumbnail">';
                        var liCont = '<li style="margin-left: 8px;">'+imgItem+'<div class="icon-close close-icon"></div></li>';
                        $('#shopPicList').append(liCont);
                    };
                    preloader.load(file.getSource());
                }
            });

        },
        'BeforeUpload': function(up, file) {
            // 每一個文件上傳前,處理相關的事情
        },
        'UploadProgress': function(up, file) {
            // 每一個文件上傳時,處理相關的事情
         },
        'FileUploaded': function(up, file, info) {
            // 上傳成功後,返回圖片路徑,domain就是上面的domain參
             var domain = up.getOption('domain');
             var res = '';
             if (typeof(info) == "string") {
                 res = $.parseJSON(info);
             } else {
                 res = info.response;
                 if (typeof(res) == "string") {
                     res = $.parseJSON(res);
                 }
             }
             uploadStoreImgUrl.push(domain + res.key);
             uploadSuccessList.push(res.key);
        },
        'Error': function(up, file, err, errTip) {
            base.hideLoading();
            //上傳出錯時,處理相關的事情
            if (file.code=='-600'){
                base.showAlertDialog('上傳圖片的大小不能超過10mb!');
            } else if (file.code=='-601'){
                base.showAlertDialog('上傳圖片的格式有誤!')
            } else {
                base.showAlertDialog(err);
            }
        },
        'UploadComplete': function(files) {
            //隊列文件處理完畢後,處理相關的事情
            // 若是上傳成功返回的圖片個數和隊列中的圖片個數同樣,則全部圖片上傳成功
            if (uploadSuccessList.length == fileNameList.length) {
                
            }

        },
        'Key': function(up, file) {
            // 若想在前端對每一個文件的key進行個性化處理,能夠配置該函數
            // 該配置必需要在 unique_names: false , save_key: false 時才生效
            var timestamp = Date.parse(new Date());
            var key = "data/car/web/uuid/"+file.name+'/'+timestamp;
            // do something with key
            return key;
        }
    }
});}});
// 這個是刪除的邏輯判斷
        $('body').on('click', '.close-icon', function () {
            var id = $(this).siblings('.pic-thumbnail').attr('id');
            var name = $(this).siblings('.pic-thumbnail').attr('name');
            var liIndex = $(this).parent().index();
            // var uploadImgList = uploadStoreImgUrl.split(',');
            // uploadStoreImgUrl = '';
            if (liIndex < uploadStoreImgUrl.length) {
                uploadStoreImgUrl.splice(liIndex,1);
            }
            
            $(this).parent().remove();
            if (!(id == undefined || id == 'undefined')) {
                storeImgObj.removeFile(id);
                $.each(fileNameList, function(index,item){
                    // index是索引值(即下標)   item是每次遍歷獲得的值;
                    if(item == name){
                        fileNameList.splice(index,1);
                    }
                });
            }
        });

以上代碼有不少邏輯處理,能夠忽略。關鍵步驟都有添加註釋,大體流程就是,
在圖片添加到上傳隊列以前,先判斷加了這些圖片是否超過了圖片的限制數量(好比10張),若是超過,則移除多餘的(預覽圖片上面有刪除按鈕,能夠刪掉,再添加寄幾想要的圖片),若是圖片有重複的,重複的也不添加,作完這些處理後,將圖片添加到上傳隊列中。
等表單提交時,觸發圖片上傳,把上傳成功後返回的圖片路徑添加到圖片成功列表和做爲表單圖片列表參數的列表,若是圖片成功列表和圖片隊列中的圖片數量一致,則提交表單。
刪除的話,做爲表單參數的列表中的圖片地址和隊列中的圖片地址也要刪除。

好吧。講真,我太囉嗦了。。。= =

相關文章
相關標籤/搜索