背景
OSS可用於圖片、音視頻、日誌等海量文件的存儲。各類終端設備、Web網站程序、移動應用能夠直接向OSS寫入或讀取數據。OSS支持流式寫入和文件寫入兩種方式。使用阿里雲oss作文件存儲的時候,不可避免的涉及到文件的上傳,大概分爲兩種方式:php
服務端驗證上傳
- 先將文件傳遞到應用服務器,再由應用服務器上傳至oss服務器,這種方式的優勢是簡單易懂,nodejs只須要按照文檔使用ali-oss中間件上傳就行,本文重點不放在這種方式,若是有須要能夠私信我。這種方式的缺點是,文件要先上傳到應用服務器,再上傳到oss,佔用帶寬資源,過程雖然簡單易於操做可是比較繁瑣。
服務端簽名前端直傳
- 這種方式是我比較推薦使用的,可是須要本身對移動端進行簽名,官方的例子給出了一個php版本的簽名服務文件,同時上傳使用的是plupload這個功能強大,可是不支持模塊化使用的插件,因而通過一番琢磨,將php版本的簽名服務改爲了js版本,同時提供axios版本的文件上傳供你們參考,親測可行。
服務代碼:前端
const crypto =require('crypto') async getSingature(ctx){ ctx.status=200; const _config={...}//裏面存放阿里雲oss的配置參數,不詳細說明,用的都應該懂 const OSSAccessKeyID=_config['spring.aliyun.oss.access-key-id'] const OSSAccessKeySecret=_config['spring.aliyun.oss.access-key-secret'] const OSSEndPoint=_config['spring.aliyun.oss.end-point'] const OSSBucketName=_config['spring.aliyun.oss.bucket-name']; let now=new Date(); const expire=300; //簽名有效時間五分鐘,可自行設定 const end = now.getTime()/1000 + expire; //過時時間 let expiration=new Date((now.getTime()/1000+expire)*1000); //oss服務器時間格式iso expiration=expiration.toISOString(); //上傳目錄 const dir= '' //上傳的限制規則 const condition=['content-length-range',0,1048576000] const start=['start-with','key',dir]; const conditions=[condition] const arr={ expiration, conditions } //上傳策略(規則對象轉json字符串) const policy=JSON.stringify(arr); //進行base64編碼 const base64_policy= (new Buffer(policy)).toString('base64'); const string_to_sign=base64_policy; //使用crypto簽名 const signature=crypto.createHmac('sha1', OSSAccessKeySecret).update(string_to_sign).digest().toString('base64'); const host="http://"+OSSBucketName+'.'+OSSEndPoint.split('//')[1]; const accessid=OSSAccessKeyID; //返回結果給前端 return { accessid, signature, policy:base64_policy, expire:end, dir, host } }
前端上傳:
注意:oss一次只能上傳一個文件(只有一個key),能夠循環執行post,key爲上傳到oss後的文件名。signatureObj這裏是上面nodejs服務端返回的簽名對象node
var file=ducument.getElementById('file').files[0] var formData = new FormData(); formData.append('key','上傳文件名'); formData.append('name',file.name) formData.append('policy',signatureObj.policy) formData.append('OSSAccessKeyId',signatureObj.accessid) formData.append('success_action_status','200') formData.append('callback','') formData.append('signature',signatureObj.signature) formData.append('file',file.file) axios({ url:url, method:'post', data:formdata, headers: { 'Content-Type': 'multipart/form-data' } })