前提條件
登錄騰訊云COS 控制臺并創(chuàng)建存儲桶,得到 Bucket(存儲桶名稱) 和 Region(地域名稱),詳情請參見創(chuàng)建存儲桶文檔。
進入存儲桶詳情頁,單擊安全管理頁簽。下拉頁面找到跨域訪問CORS設(shè)置配置項,單擊添加規(guī)則,配置示例如下圖,詳情請參見設(shè)置跨域訪問文檔。

登錄訪問管理控制臺, 獲取您的項目 SecretId 和 SecretKey。
注意:
騰訊云COS特惠活動,新人1元起,還有更多好禮等你來揭曉!
實踐步驟
注意:
正式部署時服務(wù)端請加一層您的網(wǎng)站本身的權(quán)限檢驗。
獲取臨時密鑰和計算簽名
出于安全考慮,簽名使用臨時密鑰,服務(wù)端搭建臨時密鑰服務(wù),可參考PHP 示例、Nodejs 示例。
如有其他語言或自行實現(xiàn)可以參考以下流程:
向服務(wù)端獲取臨時密鑰,服務(wù)端首先使用固定密鑰 SecretId、SecretKey 向 STS 服務(wù)獲取臨時密鑰,得到臨時密鑰 tmpSecretId、tmpSecretKey、sessionToken,詳情請參考臨時密鑰生成及使用指引或cos-sts-sdk文檔。
前端通過 tmpSecretId、tmpSecretKey,以及 method、pathname 計算簽名,可參考下文使用cos-auth.js來計算簽名,如果業(yè)務(wù)需要也可以放在后端計算簽名。
如果使用 PutObject 接口上傳文件,將計算得到的簽名和 sessionToken,分別放到發(fā)請求時 header 的 authorization 和 x-cos-security-token 字段里。
如果使用 PostObject 接口上傳文件,則將計算得到的簽名和 sessionToken,分別放到發(fā)請求時表單的 Signature 和 x-cos-security-token 字段里。
前端上傳
方案 A:使用 AJAX 上傳
AJAX 上傳需要瀏覽器支持基本的 HTML5 特性,當前方案使用PUT Object?文檔,操作指引如下:
按照前提條件的步驟,準備存儲桶的相關(guān)配置。
創(chuàng)建test.html文件,修改下方代碼的 Bucket 和 Region,并復(fù)制到test.html文件。
部署后端的簽名服務(wù),并修改test.html里的簽名服務(wù)地址。
將test.html放在 Web 服務(wù)器下,并通過瀏覽器訪問頁面,測試文件上傳功能。
Ajax Put 上傳h1,h2{font-weight: normal;? ? ? ? }#msg{margin-top:10px;? ? ? ? }
Ajax Put 上傳
(function() {// 請求用到的參數(shù)varBucket='examplebucket-1250000000';varRegion='ap-guangzhou';varprotocol = location.protocol==='https:'?'https:':'http:';varprefix = protocol +'//'+Bucket+'.cos.'+Region+'.myqcloud.com/';// prefix 用于拼接請求 url 的前綴,域名使用存儲桶的默認域名// 對更多字符編碼的 url encode 格式varcamSafeUrlEncode =function(str) {returnencodeURIComponent(str)? ? ? ? ? ? ? ? .replace(/!/g,'%21')? ? ? ? ? ? ? ? .replace(/'/g,'%27')? ? ? ? ? ? ? ? .replace(/\(/g,'%28')? ? ? ? ? ? ? ? .replace(/\)/g,'%29')? ? ? ? ? ? ? ? .replace(/\*/g,'%2A');? ? ? ? };// 計算簽名vargetAuthorization =function(options, callback) {// var url = 'http://127.0.0.1:3000/sts-auth' +varurl ='../server/sts.php';varxhr =newXMLHttpRequest();? ? ? ? ? ? xhr.open('GET', url,true);? ? ? ? ? ? xhr.onload=function(e) {varcredentials;try{? ? ? ? ? ? ? ? ? ? credentials = (newFunction('return '+ xhr.responseText))().credentials;? ? ? ? ? ? ? ? }catch(e) {}if(credentials) {callback(null, {SecurityToken: credentials.sessionToken,Authorization:CosAuth({SecretId: credentials.tmpSecretId,SecretKey: credentials.tmpSecretKey,Method: options.Method,Pathname: options.Pathname,? ? ? ? ? ? ? ? ? ? ? ? })? ? ? ? ? ? ? ? ? ? });? ? ? ? ? ? ? ? }else{console.error(xhr.responseText);callback('獲取簽名出錯');? ? ? ? ? ? ? ? }? ? ? ? ? ? };? ? ? ? ? ? xhr.onerror=function(e) {callback('獲取簽名出錯');? ? ? ? ? ? };? ? ? ? ? ? xhr.send();? ? ? ? };// 上傳文件varuploadFile =function(file, callback) {varKey='dir/'+ file.name;// 這里指定上傳目錄和文件名getAuthorization({Method:'PUT',Pathname:'/'+Key},function(err, info) {if(err) {alert(err);return;? ? ? ? ? ? ? ? }varauth = info.Authorization;varSecurityToken= info.SecurityToken;varurl = prefix +camSafeUrlEncode(Key).replace(/%2F/g,'/');varxhr =newXMLHttpRequest();? ? ? ? ? ? ? ? xhr.open('PUT', url,true);? ? ? ? ? ? ? ? xhr.setRequestHeader('Authorization', auth);SecurityToken&& xhr.setRequestHeader('x-cos-security-token',SecurityToken);? ? ? ? ? ? ? ? xhr.upload.onprogress=function(e) {console.log('上傳進度 '+ (Math.round(e.loaded/ e.total*10000) /100) +'%');? ? ? ? ? ? ? ? };? ? ? ? ? ? ? ? xhr.onload=function() {if(/^2\d\d$/.test(''+ xhr.status)) {varETag= xhr.getResponseHeader('etag');callback(null, {url: url,ETag:ETag});? ? ? ? ? ? ? ? ? ? }else{callback('文件 '+Key+' 上傳失敗,狀態(tài)碼:'+ xhr.status);? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? };? ? ? ? ? ? ? ? xhr.onerror=function() {callback('文件 '+Key+' 上傳失敗,請檢查是否沒配置 CORS 跨域規(guī)則');? ? ? ? ? ? ? ? };? ? ? ? ? ? ? ? xhr.send(file);? ? ? ? ? ? });? ? ? ? };// 監(jiān)聽表單提交document.getElementById('submitBtn').onclick=function(e) {varfile =document.getElementById('fileSelector').files[0];if(!file) {document.getElementById('msg').innerText='未選擇上傳文件';return;? ? ? ? ? ? }? ? ? ? ? ? file &&uploadFile(file,function(err, data) {console.log(err || data);document.getElementById('msg').innerText= err ? err : ('上傳成功,ETag='+ data.ETag);? ? ? ? ? ? });? ? ? ? };? ? })();執(zhí)行效果如下圖:

方案 B:使用 Form 表單上傳
Form 表單上傳支持低版本的瀏覽器的上傳(如 IE8),當前方案使用Post Object?接口。操作指引:
按照前提條件的步驟,準備存儲桶。
創(chuàng)建test.html文件,修改下方代碼的 Bucket 和 Region,并復(fù)制到test.html文件。
部署后端的簽名服務(wù),并修改test.html里的簽名服務(wù)地址。
在test.html同一個目錄下,創(chuàng)建一個空的empty.html,用于上傳成功時跳轉(zhuǎn)回來。
將test.html和empty.html放在 Web 服務(wù)器下,并通過瀏覽器訪問頁面,測試文件上傳功能。
Form 表單簡單上傳h1,h2{font-weight: normal;}#msg{margin-top:10px;}
Form 表單簡單上傳(兼容 IE8)
執(zhí)行效果如下圖:
