简单cos上传的话,看下步骤,思路就一目了然了。
1.请求自己服务器的接口 拿到cos的临时秘钥
请求接口,拿到秘钥,秘钥大约拿到这些参数:
2. 用临时秘钥初始化一个cos实例
首先确保你有cos插件,参照官方文档:
npm i cos-js-sdk-v5
然后,用刚刚的临时秘钥生成实例:
const cosInstance = new COS({
getAuthorization: (_, callback) => {
callback(config);
},
});
3.上传文件
如果过期的话,重新走上面的步骤。
官方的系列文档,官方的uploadFile接口兼容分片上传,还是蛮方便的。
不过期的话,就可以上传文件了
cosInstance.uploadFile(params)
这里注意文件名,很多时候是唯一的,所谓的key就是路径+唯一文件名+文件后缀,下面简单示例一个:
// fileObject不是原生的file,而是普通对象,结构在下面文字
const cosUploadFile = (fileObject) => {
const suffix = fileObject.name.slice(fileObject.name.lastIndexOf('.'));
const key = cosConfig.Path + getUuid() + suffix
cosInstance.uploadFile(
{
...cosConfig,
Key:key,
Body: fileObject.originFileObj, /* 必须 */
onProgress(progressData) {
// 需要显示进度的话
fileObject.progress = Math.floor(progressData.percent * 100);
},
},
(err) => {
if (err) {
console.log(err)
// 需要显示状态的话
fileObject.status = 'fail';
return;
}
// 上传成功的话,就有url了
fileObject.status = 'done';
fileObject.url = `${cosConfig.ServerName}${key}`;
},
);
};
function getUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
fileObject一般比较好的数据结构,参考antd:
demo:利用antd的upload实现cos上传单个文件
刚入门react,思路仅做参考:
import React, { useState, useEffect } from 'react';
import { Upload, message, Button,Image } from 'antd';
import { PlusOutlined,LoadingOutlined } from '@ant-design/icons';
import COS from 'cos-js-sdk-v5';
// TODO 根据自己的接口调整
export async function getConfigAjax() {
return {
state:1,
success:true,
data:{
bucketName:'',
expiredTime:'',
region:'',
serverName:'',
sessionToken:'',
startTime:'',
tmpSecretId:'',
tmpSecretKey:'',
uploadPath:'',
}
}
}
export default (props) => {
const [loading, setLoading] = useState(false);
const [imageUrl, setImageUrl] = useState(props.imageUrl);
const [cosInstance, setCosInstance] = useState(null);
const [cosConfig, setCosConfig] = useState(null);
const [fileList, setFileList] = useState([]);
const requestCosConfigAndGetCosInstance = async () => {
const res = (await getConfigAjax()).data;
const isSuccess = res.success === true;
if (!isSuccess) {
message.error('服务器有问题,请稍候再试');
return;
}
const {
bucketName,
expiredTime,
region,
serverName,
sessionToken,
startTime,
tmpSecretId,
tmpSecretKey,
uploadPath,
} = res.data;
// Key是path和文件名的拼接 Body是file文件
const config = {
TmpSecretId: tmpSecretId,
TmpSecretKey: tmpSecretKey,
XCosSecurityToken: sessionToken,
// 是10位的话就不用再除以1000了
StartTime: Math.floor(startTime/1000),
ExpiredTime: Math.floor(expiredTime/1000),
Bucket: bucketName,
Region: region,
Path: uploadPath,
ServerName: serverName,
};
setCosConfig(config);
const instance = new COS({
getAuthorization: (_, callback) => {
callback(config);
},
});
setCosInstance(instance);
};
const detectExpired = () => {
const isExpired = +new Date() >= cosConfig.ExpiredTime * 1000;
isExpired && requestCosConfigAndGetCosInstance();
};
// antd这边的fileObject属性已经封装好,所以可直接使用
const cosUploadFile = (fileObject) => {
setLoading(true)
const suffix = fileObject.name.slice(fileObject.name.lastIndexOf('.'));
const newName = fileObject.uid + suffix
const key = cosConfig.Path + newName
cosInstance.uploadFile(
{
...cosConfig,
Key:key,
Body: fileObject.originFileObj,
onProgress(progressData) {
console.log(fileObject,progressData)
fileObject.progress = Math.floor(progressData.percent * 100);
},
},
(err) => {
setLoading(false)
if (err) {
console.log(err)
fileObj.status = 'fail';
return;
}
fileObject.status = 'done';
fileObject.url = `${cosConfig.ServerName}${key}`;
setImageUrl(fileObject.url)
},
);
};
useEffect(() => {
requestCosConfigAndGetCosInstance();
}, []);
const uploadAttrs = {
name: 'file',
className:"file-uploader",
listType:"picture-card",
showUploadList:false,
maxCount:1,
onChange: ({ fileList }) => {
console.log('fileList', fileList);
setFileList(fileList)
// const { onChange } = props;
// if (onChange) {
// onChange([...fileList]);
// }
},
customRequest: () => {
detectExpired();
fileList && fileList.length && cosUploadFile(fileList[0]);
},
};
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined/>}
</div>
);
return (
<Upload { ...uploadAttrs} >
{imageUrl ? (<Image preview={false} width={200} src={imageUrl} />) : uploadButton}
</Upload>
);
};