January 07,2022
再注册一个子账户,用子账户登录
点击新建密钥生成密钥
https://cloud.tencent.com/document/product/436/14048
4.1 在node项目中安装qcloud-cos-sts
npm i qcloud-cos-sts --save
app.js 设置允许跨域访问和路由
...
// 支持跨域访问
app.all('*', function (req, res, next) {
res.header('Content-Type', 'application/json');
res.header('Access-Control-Allow-Origin', 'http://127.0.0.1');
res.header('Access-Control-Allow-Headers', 'origin,accept,content-type');
if (req.method.toUpperCase() === 'OPTIONS') {
res.end();
} else {
next();
}
});
//路由
app.get('/tx/sts', stsController.getCredential)
________________________________
stsController.js
var STS = require('qcloud-cos-sts');
// 配置参数
var config = {
secretId: 'AKI**********************IDq', //控制台获取到的secretId
secretKey: 'NUJ**********************wQdZ', //控制台获取到的secretKey
proxy: '',
durationSeconds: 1800,
// 放行判断相关参数
bucket: 'fr****-125******2', // 存储桶名称
region: 'ap-shanghai', // 所属地域
allowPrefix: 'exampleobject', // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
// 简单上传和分片,需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
allowActions: [
// 简单上传
'name/cos:PutObject',
'name/cos:PostObject',
// 分片上传
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload'
],
};
module.exports={
getCredential: (req,res)=>{
var shortBucketName = config.bucket.substr(0 , config.bucket.lastIndexOf('-'));
var appId = config.bucket.substr(1 + config.bucket.lastIndexOf('-'));
var policy = {
'version': '2.0',
'statement': [{
'action': config.allowActions,
'effect': 'allow',
'principal': {'qcs': ['*']},
'resource': [
'qcs::cos:' + config.region + ':uid/' + appId + ':prefix//' + appId + '/' + shortBucketName + '/' + config.allowPrefix,
],
}],
};
STS.getCredential({
secretId: config.secretId,
secretKey: config.secretKey,
proxy: config.proxy,
durationSeconds: config.durationSeconds,
policy: policy,
}, function (err, tempKeys) {
var result = JSON.stringify(err || tempKeys) || '';
console.log('result: ',result)
res.send(result)
});
}
}
______________________________________
cos.html
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/cos-js-sdk-v5/dist/cos-js-sdk-v5.min.js"></script>
</head>
<body>
<input type="file" onchange="uploadImg()">
<script>
var Bucket = 'f****-*******32'; /* 存储桶,必须字段 */
var Region = 'ap-shanghai'; /* 存储桶所在地域,必须字段 */
// 初始化实例
var cos = new COS({
// getAuthorization 必选参数
getAuthorization: function (options, callback) {
var url = 'http://127.0.0.1:3000/tx/sts'; // url替换成您自己的后端服务
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
try {
var data = JSON.parse(e.target.responseText);
var credentials = data.credentials;
} catch (e) {
}
if (!data || !credentials) {
return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2))
};
let obj = {
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
SecurityToken: credentials.sessionToken,
// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
}
console.log(obj)
callback(obj);
};
xhr.send();
}
});
// 接下来可以通过 cos 实例调用 COS 请求。
function myUpload(name,fileObject) {
// 不需要在每个方法里创建一个 COS SDK 实例
cos.putObject({
Bucket: Bucket, /* 必须 */
Region: Region, /* 存储桶所在地域,必须字段 */
Key: 'exampleobject', /* 必须 */
StorageClass: 'STANDARD',
Body: fileObject, // 上传文件对象
onProgress: function(progressData) {
console.log(JSON.stringify(progressData));
}
}, function(err, data) {
console.log(err || data);
});
}
// 上传图片
function uploadImg() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
let base64Url = reader.result;
var body = dataURLtoBlob(base64Url);
myUpload(file.name,body)
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
// dataURL 转 blob
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
};
</script>
</body>
</html>
到这为止,前端可以获取到上传图片所需要的Credential了,但是会看到
所以腾讯云那里还需要设置跨域
https://cloud.tencent.com/document/product/436/13318
https://cloud.tencent.com/document/product/436/11488
但我现在是本地开发,跨域设置要有域名,就想着去hosts改改,骗骗他看看行不行
在这里改成自己配置的域名
再试一次,跨域问题解决了,嘻嘻
测试传了一张图片,报了403 Forbidden,Access Denied。
原来node.js config中的的allowPrefiex相当于是允许上传到哪个文件夹,前端上传的时候要在文件key中写上这个文件夹的名称,要不然就会报403.
node.js文件
html文件
配置成这样,就不报403了
登录控制台,可以看到有ticket文件夹
上传的图片有了
随便选一个预览,可以哦
要看清楚文档,之前我上传图片直接上传dataURL格式,能传上去,但是预览错误,看了文档才发现要转成blob。所以文档一定要看清楚
https://cloud.tencent.com/document/product/436/64960
腾讯云提供了以下几个方法
但在使用之前要在后端的config中加上下载权限
https://cloud.tencent.com/document/product/436/31923
上一篇 下一篇