默認狀況下,若是以指定key或者saveKey的方式上傳一個和已經存在於空間中的文件名字相同並且內容相同的文件的時候,七牛服務器會根據新上傳的文件內容的hash推斷出該文件已經存在,不會覆寫已有的文件。
若是上傳的文件被指定的名字和空間中已有文件的名字相同,可是內容不一樣時,會返回以下錯誤信息 {「error」:「file exists」}。html
問:若是真的有這種文件內容不一樣,可是須要指定相同名字的覆蓋上傳需求怎麼辦呢?
答:很簡單,設置PutPolicy裏面的scope和insertOnly參數,而且在POST請求裏面指定須要覆蓋的文件的key。在覆蓋上傳裏面,scope的值須要設置爲bucket:key這樣的方式,這個key和POST請求裏面的key值相同,另外必須保證insertOnly爲0,這樣,文件就能夠覆蓋上傳了。前端
覆蓋上傳文件的步驟:
1. 按照bucket:key的方式設置PutPolicy裏面的scope參數,另外設置insertOnly參數爲0。
2. 構建包含指定要覆蓋的文件的key,文件內容和上傳token的表單
3. 向七牛雲存儲服務器提交HTTP POST請求
4. 解析七牛雲存儲服務器返回的回覆。vue
文件上傳以後,七牛雲存儲對文件的命名遵循如下的規則:
1. 文件上傳的POST請求中,若是指定了參數key,那麼以key來命名文件。
2. 文件上傳的POST請求中,沒有指定參數key,可是上傳策略PutPolicy裏面指定了saveKey參數,那麼以saveKey命名文件。
3. 文件上傳的POST請求中,若是沒有指定參數key,並且在上傳策略PutPolicy裏面也沒有指定saveKey參數,那麼七牛雲存儲服務器會使用根據文件內容計算得來的hash值做爲文件的名字。
備註:
上面的命名方式是按順序檢測的,一旦確認了文件的名字,就不會再檢測後面的規則。好比同時指定了表單參數key和上傳策略參saveKey,那麼也是以key來命名上傳的文件。
七牛雲存儲服務器會對每一個上傳的文件都會計算它的hash值,因此上傳的文件必定是有名字的。html5
使用 Formdata 方式上傳,表單的參數 key 指定文件要保存的名字(文件key)。webpack
在使用覆蓋上傳的時候,必須指定參數 key。git
文件上傳後的命名將遵循如下規則:github
Key
,以Key
命名。Key
,上傳策略中設置了saveKey
,以saveKey
的格式命名。Key
,上傳策略中未設置saveKey
,以文件hash(etag)
命名。
vue中使用七牛上傳,我作了一個例子(vue init webpack構建,實現了斷點續傳、暫停上傳、繼續上傳),github地址:https://github.com/cag2050/qiniu_demoweb
七牛使用 Formdata 方式上傳,缺點:npm
1. IE 8/9 不支持。json
2. 沒法使用分片上傳功能(分片上傳功能實現了斷點續傳、暫停和繼續)。
不考慮兼容性的狀況下,如手機端,可使用 Formdata 結合七牛表單上傳的方式上傳文件。
斷點續傳的含義:配置項 chunk_size 值爲0時表示不使用分片上傳功能(分片上傳功能實現了斷點續傳)
分片上傳 =====
分片上傳是將一個文件分爲多個尺寸相同的小數據塊,每一個小數據塊以一個獨立的 HTTP 請求分別上傳。全部小數據塊都上傳完成後,再發送一個請求給服務端將這些小數據塊組織成一個邏輯資源,以完成上傳過程。
缺點:相比表單上傳,分片上傳須要屢次 HTTP 請求才能完成上傳過程,會有額外的成本開銷。另外也增長了代碼的複雜度,所以選擇是否使用分片上傳時應謹慎評估使用的必要性。(我的看法:此處能夠判斷文件大小,若是很大,才用分片上傳)
斷點續傳 =====
雖然片的存在週期並不是永久,但已足以實現斷點續傳機制。
每成功上傳一個片,客戶端都會收到服務端返回一個表明當前已上傳多少片的進度信息,咱們稱之爲Context
。上傳下一個片時應提供前一個片上傳成功後返回的Context
。所以,這個Context
能夠認爲是片傳輸進度的一個標記。
若是上傳過程當中,服務端發現一個塊已經被片數據裝滿,那麼最後一個片上傳成功後返回的Context
將是一個特殊的值EOB
,告訴客戶端不要再往這個塊附加更多的片。
若是客戶端在每次收到Context
信息時都將其持久化到本地,即便客戶端程序意外崩潰或正常重啓,均可以在啓動時讀取上一次上傳成功的片對應的Context
,從而接着繼續傳輸剩餘片。這個效果咱們稱之爲斷點續傳。
斷點續上傳功能對上傳一個須要較長時間(例如一天時間才能上傳完畢)的大文件頗有價值,畢竟咱們很難保證這段很長的時間內客戶端都不會被關閉,且網絡一直處於鏈接狀態。當前主流的移動平臺(iOS、Android、Windows Phone 8)都有監測非活動應用並自動將其關閉的功能,這意味着在移動平臺上咱們要上傳一個大文件時更容易遇到中途程序忽然被關閉的狀況,斷點續傳也就更有價值。
支持斷點續傳功能以後,在客戶端很天然能夠支持一個新功能:暫停或恢復某個文傳的上傳過程。
uploader爲一個plupload對象,繼承了全部plupload的方法,以下所示初始化:
var uploader = Qiniu.uploader({
var uploader = Qiniu.uploader({ runtimes: 'html5,flash,html4', // 上傳模式,依次退化 browse_button: 'pickfiles', // 上傳選擇的點選按鈕,必需 // 在初始化時,uptoken,uptoken_url,uptoken_func三個參數中必須有一個被設置 // 切若是提供了多個,其優先級爲uptoken > uptoken_url > uptoken_func // 其中uptoken是直接提供上傳憑證,uptoken_url是提供了獲取上傳憑證的地址,若是須要定製獲取uptoken的過程則能夠設置uptoken_func // uptoken : '<Your upload token>', // uptoken是上傳憑證,由其餘程序生成 uptoken_url: 'http://localhost:9090/videos/token', // Ajax請求uptoken的Url,強烈建議設置(服務端提供) // uptoken_func: function(file){ // 在須要獲取uptoken時,該方法會被調用 // // do something // return uptoken; // }, get_new_uptoken: false, // 設置上傳文件的時候是否每次都從新獲取新的uptoken // downtoken_url: '/downtoken', // Ajax請求downToken的Url,私有空間時使用,JS-SDK將向該地址POST文件的key和domain,服務端返回的JSON必須包含url字段,url值爲該文件的下載地址 //unique_names: true, // 默認false,key爲文件名。若開啓該選項,JS-SDK會爲每一個文件自動生成key(文件名) save_key: true, // 默認false。若在服務端生成uptoken的上傳策略中指定了sava_key,則開啓,SDK在前端將不對key進行任何處理 domain: 'qujsh1', // bucket域名,下載資源時用到,必需 container: 'video_container', // 上傳區域DOM ID,默認是browser_button的父元素 max_file_size: '500mb', // 最大文件體積限制 flash_swf_url: '/plupload/Moxie.swf', //引入flash,相對路徑 max_retries: 3, // 上傳失敗最大重試次數 dragdrop: true, // 開啓可拖曳上傳 drop_element: 'video_container', // 拖曳上傳區域元素的ID,拖曳文件或文件夾後可觸發上傳 chunk_size: '4mb', // 分塊上傳時,每塊的體積 auto_start: true, // 選擇文件後自動上傳,若關閉須要本身綁定事件觸發上傳 //x_vars : { // 查看自定義變量 // 'time' : function(up,file) { // var time = (new Date()).getTime(); // do something with 'time' // return time; // }, // 'size' : function(up,file) { // var size = file.size; // do something with 'size' // return size; // } //}, init: { 'FilesAdded': function(up, files) { plupload.each(files, function(file) { // 文件添加進隊列後,處理相關的事情 }); }, 'BeforeUpload': function(up, file) { // 每一個文件上傳前,處理相關的事情 }, 'UploadProgress': function(up, file) { // 每一個文件上傳時,處理相關的事情 }, 'FileUploaded': function(up, file, info) { //console.log(info); // 每一個文件上傳成功後,處理相關的事情 // 其中info是文件上傳成功後,服務端返回的json,形式如: // { // "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98", // "key": "gogopher.jpg" // } // 查看簡單反饋 // var domain = up.getOption('domain'); // var res = parseJSON(info); // var sourceLink = domain +"/"+ res.key; 獲取上傳成功後的文件的Url }, 'Error': function(up, err, errTip) { //上傳出錯時,處理相關的事情 }, 'UploadComplete': function() { //隊列文件處理完畢後,處理相關的事情 }, 'Key': function(up, file) { // 若想在前端對每一個文件的key進行個性化處理,能夠配置該函數 // 該配置必需要在unique_names: false,save_key: false時才生效 var key = ""; // do something with key here return key } } });
其中的屬性說明:
domain:爲七牛空間對應的域名,選擇某個空間後,可經過 空間設置->基本設置->域名設置 查看獲取
plupload.js版本低的話,會報錯誤:ReferenceError: mOxie is not defined。
由於plupload js在2.2.0開始,就去掉了mOxie 這個變量;因此建議使用 plupload js 的版本是在 2.1.1 到 2.1.9。(我用的是2.1.9版本)
npm已沒法安裝低版本。