七牛云js-sdk應(yīng)用總結(jié)
基本思路
- 首先,整個(gè)七牛云sdk的思路是,先去服務(wù)器端拿uptoken,前段js來操作上傳,后端部分這里采用php。
- js-sdk是依賴于plupload的,plupload是一個(gè)上傳插件,所以應(yīng)該下載的資源有,php-sdk,js-sdk以及plupload插件。另外,官網(wǎng)給的demo是基于bootstrap的,所以也要把bootstrap下載一下。
- 直接把官網(wǎng)給的demo跑通是最高效的熟悉方式。
- 將官網(wǎng)文檔看一下,了解七牛云的工作流程以及代碼。
準(zhǔn)備工作和文件介紹
- 首先,你應(yīng)該已經(jīng)注冊(cè)了七牛云的賬號(hào),進(jìn)入‘對(duì)象存儲(chǔ)’,創(chuàng)建了一個(gè)空間,會(huì)看到一個(gè)類似下面這樣的域名
ogd29n56i.bkt.clouddn.com
在“個(gè)人面板”->“秘鑰管理”應(yīng)該也能看到你自己的秘鑰對(duì)。
- 下載qiniu/php-sdk,js-sdk,plupload,bootstrap
- js-sdk中包含了官網(wǎng)的demo,在index.html中引入前面下載的資源,加載順序要注意一下:
css
<link rel="stylesheet" type="text/css" href="{{url('/qiniu/bootstrap/css/bootstrap.css')}}">
<link rel="stylesheet" type="text/css" href="{{url('/qiniu/js/highlight/highlight.css')}}">
js部分
<script type="text/javascript" src="{{url('/qiniu/js/jquery.js')}}"></script>
<script type="text/javascript" src="{{url('/qiniu/js/plupload/plupload.full.min.js')}}"></script>
<script type="text/javascript" src="{{url('/qiniu/js/plupload/i18n/zh_CN.js')}}"></script>
<script type="text/javascript" src="{{url('/qiniu/js/qiniu.js')}}"></script>
<script type="text/javascript" src="{{url('/qiniu/js/ui.js')}}"></script>
<script type="text/javascript" src="{{url('/qiniu/js/main.js')}}"></script>
關(guān)于js引入的順序,plupload是基于jquery的,而七牛的sdk又是基于plupload的,所以應(yīng)該先引入jquery再plupload,再qiniu.js,那么main.js和ui.js是什么呢?
main.js是云存儲(chǔ)的初始化代碼,就是七牛js-sdk官網(wǎng)文檔的“上傳”部分的代碼。
在這部分代碼中,有關(guān)于初始化的屬性設(shè)置,例如:
var uploader = Qiniu.uploader({
runtimes: 'html5,flash,html4',
browse_button: 'pickfiles',
container: 'container',
drop_element: 'container',
max_file_size: '1000mb',
flash_swf_url: 'bower_components/plupload/js/Moxie.swf',
dragdrop: true,
chunk_size: '4mb',
......
也有回調(diào)函數(shù)和數(shù)據(jù),例如
'BeforeUpload': function(up, file) {
var progress = new FileProgress(file, 'fsUploadProgress');
var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
if (up.runtime === 'html5' && chunk_size) {
progress.setChunkProgess(chunk_size);
}
},
上面這個(gè)函數(shù)定義了上傳開始之前的動(dòng)作,括號(hào)內(nèi)的up和file是兩個(gè)對(duì)象,里面包含了關(guān)于在上傳這個(gè)文件的所有信息,可以將他們打印出來看看。
同樣的,也有上傳中,上傳完成后等等回調(diào)函數(shù)。那么在這些函數(shù)中經(jīng)常會(huì)進(jìn)行一些DOM操作,本例中,將這些DOM操作都封裝在ui.js中。好了,這幾個(gè)文件介紹好之后,現(xiàn)在開始正式看看,七牛云是怎樣工作的。
具體操作流程
因?yàn)檎麄€(gè)流程是圍繞main.js展開的,我們就按照這個(gè)文件來展開介紹七牛云上傳的所有細(xì)節(jié)。我們只說幾個(gè)核心的點(diǎn),其他的看文檔就行了。
- 文件上傳按鈕
var uploader = Qiniu.uploader({
runtimes: 'html5,flash,html4',
browse_button: 'pickfiles',
container: 'container',
...
browse_button,container后面的值對(duì)應(yīng)了頁(yè)面中兩個(gè)元素的id值,并且container應(yīng)該包含pickfiles,所以在html中寫入下面內(nèi)容
<div id="container">
<button id="pickfiles">選擇文件</button>
</div>
- uptoken和domain
domain上面說過了,是你的七牛云生成的空間域名,一個(gè)域?qū)?yīng)一個(gè)空間,有些坑后面再講。
uptoken是一個(gè)簽證,這個(gè)js腳本運(yùn)行之后,main.js會(huì)異步去你指定的鏈接拿到uptoken的值
所以,關(guān)于這兩個(gè)東西你得做三個(gè)事情:(我這么寫不安全,自己發(fā)揮)
一是前端寫入隱藏dom
<input type="hidden" id="domain" value="http://ogd29n56i.bkt.clouddn.com/">
<input type="hidden" id="uptoken_url" value="{{url('getuptoken')}}">
二是寫入main.js
uptoken_url: $('#uptoken_url').val(),
domain: $('#domain').val(),
第三步就是寫好獲取uptoken的php程序,這部分也比較簡(jiǎn)單,可以參考官方php文檔,附上代碼:
public function getUptoken()
{
// 需要填寫你的 Access Key 和 Secret Key
$accessKey = 'VsAP-hK_hVPKiq5CQcoxWNhBT9ZpZ1Ii4z3O_W51';
$secretKey = '5dqfmvL15DFoAK1QzaVF2TwVzwJllOF8K4Puf1Po';
// 構(gòu)建鑒權(quán)對(duì)象
$auth = new Auth($accessKey, $secretKey);
// 要上傳的空間
$bucket = 'jacklin';
// 生成上傳 Token
$token = $auth->uploadToken($bucket);
$res = array('uptoken'=>$token);
return response()->json($res);
}
3.到目前為止,上傳功能已經(jīng)可以實(shí)現(xiàn)了,其他的設(shè)置你也需要看一下,比如方便的設(shè)置文件大小上限,哪幾個(gè)不能同時(shí)設(shè)置之類的。
4.上文有說過,js版本的sdk結(jié)合了plupload這個(gè)上傳插件,所以還有很多便利的地方。那就是main.js下面的部分。
'FilesAdded': function(up, files) {}
'BeforeUpload': function(up, file) {}
'UploadProgress': function(up, file) {}
'UploadComplete': function() {}
'FileUploaded': function(up, file, info) {}
'Error': function(up, err, errTip) {}
'Key': function(up, file) {}
先大概了解一下這幾個(gè)函數(shù),這里的用法類似jQ的ajax,這些是回調(diào)函數(shù)和參數(shù),其中的up,files,info里面包含了關(guān)于這個(gè)文件所有的信息,
包括文件類型,大小,成功后的鏈接等等,所以可以用這些信息做一些DOM操作,首先前端的展示和必要的數(shù)據(jù)獲取。如果你想查看這些對(duì)象里面
的內(nèi)容咋辦呢?
for(i in json){
console.log(i);
console.log(json[i]);
}
5 下面詳細(xì)講解這幾個(gè)函數(shù)
'FilesAdded': function(up, files) {
//這里定義文件加入上傳隊(duì)列,但是還沒有開始上傳的動(dòng)作
//七牛jssdk是多文件上傳的,你可以試試上傳的時(shí)候Ctrl添加多個(gè)文件試試
//第一個(gè)在加載的時(shí)候其他的文件的狀態(tài)就是FilesAdded
},
'BeforeUpload': function(up, file) {
//這里自定義了上傳前的動(dòng)作,上傳前就是馬上就要開始上傳的臨界點(diǎn)
},
'UploadProgress': function(up, file) {
//這里自定義上傳中的動(dòng)作,這個(gè)地方就比較有意思了,只要文件上傳沒有完成
//這個(gè)函數(shù)就不斷回調(diào),你可以寫一個(gè)alert(1)試試,文件上傳中,就不斷的彈彈彈
}
'UploadComplete': function() {
//這里自定義上傳完成時(shí)的動(dòng)作
},
'FileUploaded': function(up, file, info) {
//這里定義了文件完成后的動(dòng)作,可能你上傳成功時(shí)通過ajax把url寫進(jìn)數(shù)據(jù)庫(kù)
//就可以把a(bǔ)jax寫在這里,從info對(duì)象里獲取到url
}
'Error': function(up, err, errTip) {
//這里定義出現(xiàn)錯(cuò)誤時(shí)的動(dòng)作
}
'Key': function(up, file) {
//這里也是一個(gè)關(guān)鍵的地方,如果你想自己定義文件名,就在這里組織,并 return key;
// 但是前提是你已經(jīng)把 unique_names save_key 注釋了,我這里是加了一個(gè)時(shí)間戳
//這里是我定義的key,其實(shí)就是字符串拼接,如果你喜歡,return '123' 都可以
var extarr = file['name'].split('.');
if(extarr.length===1){
var arr=file['type'].split('/');
var prename = extarr[0];
var ext = (arr[arr.length-1]=='undefined')?'':arr[arr.length-1];
}else{
var ext = '.'+ extarr[extarr.length-1]; //得到后綴
var index = file['name'].lastIndexOf('.');//得到最后一個(gè)點(diǎn)的坐標(biāo)
var prename = file['name'].substring(0,index);//得到最后一個(gè)點(diǎn)之前的字符串
}
var time = Date.parse(new Date())/1000;
$("input[name='ftype']").val(prename);
var key = prename+'/'+time+ ext;
return key;
}
6 .到現(xiàn)在整個(gè)流程已經(jīng)講完了,下面講這個(gè)ui.js,你打開這個(gè)文件可能嚇一跳,哇塞,js面向?qū)ο螅鞣N成員屬性方法的,
其實(shí)ui.js是官網(wǎng)demo的dom操作,沒有這個(gè)js,官網(wǎng)這個(gè)demo能上傳文件,但是,你啥都看不到,他就是用了上面所說up,
files,info幾個(gè)對(duì)象里面的信息結(jié)合了幾個(gè)過程,展示出了一些信息。它定義了一個(gè)FileProgress對(duì)象,而這個(gè)對(duì)象是初始化了
一個(gè)dom元素作為他的容器,你看一下他大概的用法,稍微了解一下up,files,info這幾個(gè)對(duì)象就可以自己寫了,不過,可是,
這個(gè)demo有關(guān)于縮略圖和大文件分塊上傳進(jìn)度展示的功能還是很復(fù)雜的。如果你說著我也會(huì)寫,那你試試。
坑
400:token not specified
出現(xiàn)這個(gè)情況,說明你離成功還很遠(yuǎn)
1.檢查你的token格式是不是跟官網(wǎng)的一樣
2.我還遇到一個(gè)更坑的情況,浪費(fèi)了很多時(shí)間,那就是電腦差,資源加載的慢,js還沒有完全加載好,我就點(diǎn)擊上傳,也報(bào)這個(gè)錯(cuò),所以,你得排除這個(gè)可能,那就是--等
400:incorrect zone ,please use up-z1.qiniu.com
這個(gè)問題是由于,你創(chuàng)建空間時(shí)候,手賤點(diǎn)了華北地區(qū),七牛每個(gè)服務(wù)域名服務(wù)的地區(qū)是規(guī)定好的,所以有兩個(gè)辦法
- 換空間: 重新建一個(gè)空間 我選華東的,就OK了
- 換域名: 打開qiniu.js 搜索 qiniuUploadUrls,修改成如下
var qiniuUploadUrls = [
'http://upload-z1.qiniu.com',
'http://up-z1.qiniu.com'
]
最后
其他的自定義設(shè)置可以參考官方文檔,下面附上一些常用的設(shè)置
1 設(shè)置一次只能選一個(gè)文件
multi_selection: false
2 取消分片 注意,最大分片也只是4M
chunk_size: ‘0mb’
3 取消自動(dòng)上傳
auto_start: false
4 暫停上傳,開始上傳
//加入下面dom和js代碼
$('#up_load2').on('click', function(){
uploader2.start();
});
$('#stop_load2').on('click', function(){
uploader2.stop();
});
5 多個(gè)上傳按鈕問題,實(shí)例化多個(gè)main.js就行了