其实用这个组件以前,原先是想接着用webuploader的,毕竟用过了,比较熟悉,并且也很好用。然鹅,由于是要上传到七牛,遇到了跨域的问题,尝试过网上的几种解决方法,都没用。只好用七牛文档里面的plupload,hhhhhh,官方文档推荐的,总归不会有什么问题~其实这篇文章咧,不是纯粹的怎么用plupload,会有一部分逻辑处理(脑子实在很差用,怕忘记了到时候还要从新想一遍逻辑,想一想仍是记下来吧)javascript
https://developer.qiniu.com/k... 这个是七牛官网Javascript SDK的文档,项目过程当中遇到的问题,也都是直接翻文档。由于用的plupload,有些参数七牛的文档没那么详细,http://www.cnblogs.com/2050/p... 这个连接是从七牛官网跳转过去的~很详细。因为官方文档已经写得很详细,这边就不过多的介绍参数、方法啥的,把项目中有注意到的参数、遇到的问题及解决方法整理一下。html
大体过程是这样的前端
能够去github上面下载SDK源码,也能够经过NPM或者Bower安装。(官网有安装教程)html5
把js文件引入,我是用plupload.full.min.js、moxie.min.js、qiniu.min.js、Moxie.swfjava
由于是前端的关系,七牛的帐号密码,包括token、下载资源用的bucket域名等这些是后台的小伙伴提供的,在用到图片上传以前,先经过后台小伙伴提供的接口请求七牛的tokenjquery
接下去就能够写代码啦(贴完代码发现本身写了好一些逻辑处理,赶忙跳上来先把一些能够分享的东西写到上面来)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张),若是超过,则移除多余的(预览图片上面有删除按钮,能够删掉,再添加寄几想要的图片),若是图片有重复的,重复的也不添加,作完这些处理后,将图片添加到上传队列中。
等表单提交时,触发图片上传,把上传成功后返回的图片路径添加到图片成功列表和做为表单图片列表参数的列表,若是图片成功列表和图片队列中的图片数量一致,则提交表单。
删除的话,做为表单参数的列表中的图片地址和队列中的图片地址也要删除。
好吧。讲真,我太啰嗦了。。。= =