-
環境:
thinkphp6
vue2
vant2.12 -
composer安裝qcloud-sts-sdk
composer require qcloud_sts/qcloud-sts-sdk
- 獲取COS臨時id、key的sts接口
<?php
declare (strict_types = 1);namespace app\index\controller;
use QCloud\COSSTS\Sts;class CosController
{//http://localhost:8516/index/cos/stspublic function sts() {$sts = new Sts();$config = array('url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致'domain' => 'sts.tencentcloudapi.com', // 域名,非必須,默認為 sts.tencentcloudapi.com'proxy' => '','secretId' => 'xxxx', // 固定密鑰,若為明文密鑰,請直接以'xxx'形式填入,不要填寫到getenv()函數中'secretKey' => 'xxxx', // 固定密鑰,若為明文密鑰,請直接以'xxx'形式填入,不要填寫到getenv()函數中'bucket' => 'test-1253653367',//'test-1253653367', // 換成你的 bucket'region' => 'ap-shanghai', // 換成 bucket 所在園區'durationSeconds' => 1800, // 密鑰有效期'allowPrefix' => array('2024/msc2024/*'), // 這里改成允許的路徑前綴,可以根據自己網站的用戶登錄態判斷允許上傳的具體路徑,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全風險, 請謹慎評估使用)// 密鑰的權限列表。簡單上傳和分片需要以下的權限,其他權限列表請看 https://cloud.tencent.com/document/product/436/31923'allowActions' => array (// 簡單上傳'name/cos:PutObject','name/cos:PostObject',// 分片上傳'name/cos:InitiateMultipartUpload','name/cos:ListMultipartUploads','name/cos:ListParts','name/cos:UploadPart','name/cos:CompleteMultipartUpload'),// 臨時密鑰生效條件,關于condition的詳細設置規則和COS支持的condition類型可以參考 https://cloud.tencent.com/document/product/436/71306// "condition" => array(// "ip_equal" => array(// "qcs:ip" => array(// "10.217.182.3/24",// "111.21.33.72/24",// )// )// ));$tempKeys = $sts->getTempKeys($config);//echo json_encode($tempKeys);return json($tempKeys);// try {// // 可能拋出異常的代碼// // 獲取臨時密鑰,計算簽名// $tempKeys = $sts->getTempKeys($config);// //echo json_encode($tempKeys);// return json($tempKeys);// } catch (\Throwable $e) {// // 異常處理代碼// return json(array('code'=>101, 'msg'=>$e->getMessage()));// }}
}
前端vue2代碼,使用vant的文件上傳組件
<van-uploader :after-read="handleUpload"></van-uploader>
data: {process: 0,isProcessVisible: false,uploadType: null, //1人像 2國徽 3自拍cos: null
}
handleUpload: function (res) {var file = res.filevar that = thisvar that = thisvar cosBucket = 'test-123456'var cosRegion = 'ap-shanghai'var cosPrefix = '2024/msc2024'let name = file.namelet size = file.sizelet ext = getFilePointExtName(name)let shortName = getFileName(name)let fileName = 'upload/' + getStrDateNoLine(new Date()) + "/" + uuid() + extlet fileKey = cosPrefix + '/' + fileNameif(ext!= '.jpg' && ext!= '.JPG' && ext!= '.png' && ext!= '.PNG') {//this.$Message.error('請上傳jpg格式文件');vant.Toast('請上傳jpg或png格式文件');return}if(size > 1024*1024*2) {vant.Toast('圖片文件不要大于2M');return}//alert(fileName)//console.log(file)if(this.cos == null) {this.cos = new COS({// getAuthorization 必選參數getAuthorization: function (options, callback) {// 初始化時不會調用,只有調用 cos 方法(例如 cos.putObject)時才會進入// 異步獲取臨時密鑰// 服務端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/// 服務端其他語言參考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk// STS 詳細文檔指引看:https://cloud.tencent.com/document/product/436/14048const url = '/index/cos/sts'; // url 替換成您自己的后端服務const xhr = new XMLHttpRequest();let data = null;let credentials = null;xhr.open('GET', url, true);xhr.onload = function (e) {try {data = JSON.parse(e.target.responseText);credentials = data.credentials;} catch (e) {}if (!data || !credentials) {return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2))};callback({TmpSecretId: credentials.tmpSecretId,TmpSecretKey: credentials.tmpSecretKey,SecurityToken: credentials.sessionToken,// 建議返回服務器時間作為簽名的開始時間,避免用戶瀏覽器本地時間偏差過大導致簽名錯誤StartTime: data.startTime, // 時間戳,單位秒,如:1580000000ExpiredTime: data.expiredTime, // 時間戳,單位秒,如:1580000000});};xhr.send();}});}// var cos = new COS({// SecretId: 'xx',// SecretKey: 'xx',// });that.isProcessVisible = truethat.process = 0this.cos.uploadFile({Bucket: cosBucket, /* 填寫自己的bucket,必須字段 */Region: cosRegion, /* 存儲桶所在地域,必須字段 */Key: fileKey, /* 存儲在桶里的對象鍵(例如:1.jpg,a/b/test.txt,圖片.jpg)支持中文,必須字段 */Body: file, // 上傳文件對象SliceSize: 1024 * 1024 * 5, /* 觸發分塊上傳的閾值,超過5MB使用分塊上傳,小于5MB使用簡單上傳。可自行設置,非必須 */onProgress: function(progressData) {//console.log(JSON.stringify(progressData));that.process = Math.floor(progressData.percent*100)}}, function(err, data) {that.isProcessVisible = falseif (err) {console.log('上傳失敗', err);} else {console.log('上傳成功');console.log('http://' + data.Location)var url = 'http://' + data.Location.replace("xxxx.cos.ap-shanghai.myqcloud.com", "cdn.xxx.xxx.com")console.log(url)}});return false
},
- 用到的其它方法
function getFileName(fileName) {let pos = fileName.indexOf(".")if(pos >= 0) {return fileName.substr(0, pos)}return fileName
}function getFileExtName(fileName) {let pos = fileName.indexOf(".")if(pos >= 0) {return fileName.substr(pos+1)}return ''
}function getFilePointExtName(fileName) {var ext = getFileExtName(fileName)if(ext != '') {return '.' + ext}return ''
}function getStrDateNoLine(date) {var y = date.getFullYear();var m = date.getMonth() + 1;//獲取當前月份的日期 var d = date.getDate();if (m < 10) {m = '0' + m;}if (d < 10) {d = '0' + d;}return y + "" + m + "" + d;
}//用于生成uuid
function S4() {return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}function uuid() {return (S4() + S4() + "" + S4() + "" + S4() + "" + S4() + "" + S4() + S4() + S4());
}