怎么上传文件到腾讯云cos,附antd例子

3,118 阅读2分钟

简单cos上传的话,看下步骤,思路就一目了然了。

cos_steps.png

1.请求自己服务器的接口 拿到cos的临时秘钥

请求接口,拿到秘钥,秘钥大约拿到这些参数: cos_config

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:

fileObject

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>
  );
};

cos_antd