一、问题的描述
目前前端上传文件提交到后台,后台接收文件上传到腾讯云。这样上传速度太慢。改成
直传方式。由前端直接对接腾讯云。
二、问题的解决方案
第一步在@/utils.ts先封装一个直传的函数
import COS from 'cos-js-sdk-v5';
// 最新计算签名
export const getAuthorizationFun = async (options: any, callbackFn: any) => {
// 初始化实例
let curObj: any = {};
const protocol = location.protocol === 'https:' ? 'https://' : 'http://';
const data = new FormData();
data.append(options.key, options.value);
const res = await getCosToken(data); // 调用后台放回的必要字段,如:sessionToken,tmpSecretId,tmpSecretKey
if (res?.code === 200) {
const time = getCurrentTime();
const randomNum = parseInt(String(Math.random() * 100000));
curObj = {
sessionToken: res.data.auth.credentials.sessionToken,
tmpSecretId: res.data.auth.credentials.tmpSecretId,
tmpSecretKey: res.data.auth.credentials.tmpSecretKey,
bucket: res.data.bucket,
dir: res.data.dir,
region: res.data.region,
method: 'PUT',
pathName: `${res.data.dir}/${time}-${randomNum}`,
startTime: res.data.auth.startTime,
expiredTime: res.data.auth.expiredTime,
protocol,
};
} else {
message.error(res?.message);
}
const cos = new COS({
// getAuthorization 必选参数
getAuthorization: (params: any, callback: any) => {
// 初始化时不会调用,只有调用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/14048
if (curObj) {
callback({
TmpSecretId: curObj.tmpSecretId,
TmpSecretKey: curObj.tmpSecretKey,
SecurityToken: curObj.sessionToken,
StartTime: curObj.startTime,
ExpiredTime: curObj.expiredTime,
});
} else {
callback('获取签名出错');
}
},
});
callbackFn(cos, curObj);
};
第二步,业务调用,开始上传
import { getAuthorizationFun } from '@/utils';
const { fileList: newFileList } = params;
if (params.file.status === 'uploading') {
/* 直接调用cos sdk的方法 */
getAuthorizationFun({ key: 'type', value: 2 }, (cos: any, curObj: any) => {
const suffix = getSuffix(params.file.name);
cos.uploadFile(
{
Bucket: curObj.bucket,
Region: curObj.region,
Key: curObj.pathName + suffix,
Body: params.file.originFileObj, // 上传文件对象
},
(err: any, data: any) => {
if (err) {
message.error(
intl.formatMessage({
id: 'component.handle.UploadFailed',
defaultMessage: `上传失败`,
}),
);
} else {
let url = curObj.protocol + data?.Location;
const reader = new FileReader();
reader.readAsArrayBuffer(params.file.originFileObj);
reader.onload = () => {
const buf: any = reader.result as string;
const md5_buf = md5(buf);
const size = params.file.size;
const obj: any = {
uid: newFileList[0].uid || '',
name: newFileList[0].name || '',
status: 'done',
url,
md5: md5_buf,
size,
};
setFlag(false);
setFileList([obj]);
setNewUrlName(params?.file?.originFileObj?.name);
setNewUrl(url);
message.success(
intl.formatMessage({
id: 'component.handle.UploadSucceed',
defaultMessage: `上传成功`,
}),
);
};
}
},
);
});
} else if (params.file.status == 'error') {
//上传错误时
message.error(
intl.formatMessage({
id: 'device.other.Upload_failed',
defaultMessage: '上传失败',
}),
);
}