为什么80%的码农都做不了架构师?>>>
七牛JS SDK使用方法
先简单介绍 JS SDK的使用方法:(官方教程参考:http://developer.qiniu.com/docs/v6/sdk/javascript-sdk.html)
-
让你的后端帮你生成 Token 上传凭证
-
引入 plupload.js(七牛 SDK 强依赖,用于处理文件上传,官网戳我)、qiniu.js(七牛 SDK)
注:plupload.js 在不同环境中需要引入的文件不同,正式环境:plupload.full.min.js, plupload.dev.js + moxie.js -
页面中进行类似如下引用即可
var uploader = Qiniu.uploader({
runtimes: 'html5,html4', //上传模式,依次退化
browse_button: 'J_avatarPickfile', //上传选择的点选按钮 DOM ID,**必需**
// uptoken_url: 'http://api.shanyue8.com/app/qiniu_upload_token', //Ajax请求upToken的Url,**强烈建议设置**(服务端提供)
uptoken : uptoken,
domain: 'http://***.qiniucdn.com/', //bucket 域名,下载资源时用到,**必需**
get_new_uptoken: false, //设置上传文件的时候是否每次都重新获取新的token
container: 'J_avatarContainer', //上传区域 DOM ID,默认是browser_button的父元素,
max_file_size: '100mb', //最大文件体积限制
max_retries: 3, //上传失败最大重试次数
dragdrop: true, //开启可拖曳上传
drop_element: 'container', //拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传
chunk_size: '4mb', //分块上传时,每片的体积
auto_start: true, //选择文件后自动上传,若关闭需要自己绑定事件触发上传
init: {
'FilesAdded': function(up, files) {
plupload.each(files, function(file) {
// 文件添加进队列后,处理相关的事情
});
},
'BeforeUpload': function(up, file) {},
'UploadProgress': function(up, file) {}, // 每个文件上传中,处理相关的事情
'FileUploaded': function(up, err, info) {}, // info:七牛返回信息
'Error': function(up, err, errTip) {}, //上传出错时,处理相关的事情
'UploadComplete': function() {}, //队列文件处理完毕后,处理相关的事情
'Key': function(up, file) {
var key = tool.getGuid() + "." + file.type.split("/")[1]; // 本人拙劣的自己写的生成 Guid 的方法
return key;
// 若想在前端对每个文件的key进行个性化处理,可以配置该函数
// 该配置必须要在 unique_names: false , save_key: false 时才生效
}
}
});
4、页面结构
5、在线上测试
踩过的那些坑
一、Token 凭证问题
图片上传需要 Token,不要问我如何生成 Token ,请自行查看(点我点我)。生成 Token 需要 AccessKey 和 SecretKey,这种私密性强的数据自然不应该在前端暴露。所以,凭证必须由后端生成。
好吧,我承认尝试过在前端生成(因为羞射不好意思找后端让帮忙啊),但是,没有提供生成的 SDK 啊,有 PHP款式,有 Node款式,偏偏没有前端款。我是不会算法的,所以看不懂那复杂的凭证生成算法。于是想到去七牛的凭证生成器扒凭证生成算法,算了,说多了都是泪,显然没成功。此处浪费时间两天。
所以,沟通很重要沟通很重要沟通真的真的很重要。重要的话说三遍...
二、图片多选问题
在属性配置中增加下列属性:
multi_selection:true; // false:单选;true:多选
更多属性参见 plupload 的配置。
三、配置上传文件的 Key 值
先来两张图感受下:
手机版
PC 版
为什么我要发两个版本的截图,就是为了告诉大家,这个我花了两天才爬出来的坑长啥样子。
Key 是你所上传的文件在七牛云中的标示符,如果你不对 Key 进行改造(譬如我整了一个 32位数的Guid),那么,文件名很可能重复。然后会报错,提示请参考上面“手机版”截图。
PC 中图片名称我就不多说,爱存咋存。关键是手机上,我用的 iPhone,没想到图片的名称竟然全部都是“image.jpeg”(七牛获取的,待我测一下原生 JS 获取的文件name)。我特么也是醉了,以前怎么没发现啊。不管怎样,总之,在使用七牛的 SDK 时,如果不对 Key 进行改造,根本无法在 iPhone 上运行。
我多么多么希望早点有人提示我,因为我特么压根没想这上面去,好吧,我的习惯是,一看到报错提示第一反应就是“我肯定又哪里搞错了”。算了,不扯犊子了。记得改造 Key,记得改造 Key,记得改造 Key。改造方法很简单,配置参数“Key”就行了。具体参见顶部代码。
四、上传选择的点选按钮不能隐藏,只要是包含它的父层也不能隐藏,否则在 iPhone 中无法使用
界面效果图
观察界面图,很容易发现,上传图片这个功能包含在一个向右滑出的层内。假设,这个层为 #slide,上传图片点选按钮为 #pickfiles。其中,#slide 的样式继承了如下两条。
{
display:none;
-webkit-transform: translateX(-100%);
}
问题出现了。我在 PC 的 Chrome 和 Safari 中测试均可用,在 Android 4.0 + 手机浏览器中可用(我用 Note2 测试,UC 不可用,原生浏览器可用,产品用小米测试可用,没问他什么浏览器),氮素,iPhone 不可用啊,不可用啊,谁能告诉我原因?我到现在为止也不知道原因。魂淡啊魂淡!我说了,我第一反应就是我的没有在 JS 文件头部加上 use strict;所以我写的那种没组织没纪律性的代码出了这种奇葩问题。于是,我开始定位问题。还好,这个功能所在 JS 文件只有 500 多行,Function 也不多,十来个。呵呵哒,折腾了一晚上也没见到效果。最后,我使出绝招,把所有功能都屏蔽,把页面中其他元素都屏蔽让上传按钮直接裸露出来,测试页面一做出来,特么能用了!!!
于是,灵光一闪,莫非跟元素被隐藏有关。去掉 #slide 上的 hide CSS 类之后,居然真的可用了!!!
天啊,我以为是 JS 的问题,没想到只有一个小小的 CSS 的问题,更没想到这个小小的问题,竟然折磨了我一天一夜,害我昨天晚上做梦梦见自己在发版本,产品突然问我“Bug改好了吗?”然后,我特么就被吓醒了。所以,请记住,一定不要隐藏上传按钮(我没试过,你可以试试),或者上传按钮的包裹层。
五、坑爹的 up.getOption
我真是醉醉的啊,先复原问题:
1、说明, up.getOption() 是用来获取我们传递的参数的接口:
console.info("up.getOption('container') : ");
console.info(up.getOption('container'));
console.info("up.getOption('browse_button') : ");
console.info(up.getOption('browse_button'));
下面是控制台打印结果:
2、你一定想知道这两个参数有什么不一样,好吧,请看下图:
总结:传入其中的两个参数都是 DOM ID,结果用它获取参数的方法,得到的结果竟然一个是 DOM ID,一个竟然是 DOM Object Array。容我哭一会去,我不管你内部如何在牛B的运作着神秘的代码,但是,可以不要挖这样的坑给使用者吗?Web 前端第三方插件的使用史就是血泪史啊,什么时候前端规范才能统一呢?也需要等到我转行之后,心塞塞。
六、改造上传 input,限制只上传图片
改造前:(我把style清空了)
改造后:
capture="camera" accept="image/*">
JS:(上下文已省略)
// 改造上传按钮,只传图片 pt._resetFileinput = function (fileinput) { // 添加只能上传图片的限制(移动端定制) fileinput.setAttribute('capture', 'camera'); fileinput.setAttribute('accept', 'image/*'); }
后语