OSS 封装上传文件

前端上传文件程序开发
基本流程
在实际项目中,一般采用分布式及微服务的 web 业务系统中,文件的上传和下载都是直接在前端来实现对 oss 的操作。也就是前端直接上传,不通过自己的服务器。这样能够实现系统无阻碍的横向扩展。另一个原因是如果要把文件保存在运行 web 服务器的同一台服务器上时,那么在文件上传时可能会占满带宽,影响 web 的访问。分开存储不占服务器带宽。

阿里 OSS 提供了三种前端直传方式:

浏览器签名后直接上传 OSS(无需服务端干预)
浏览器请求服务器签名地址后上传(需要服务端配合)
浏览器请求服务器签名地址后上传并回调服务端(需要服务端配合)
实际生产环境考虑到安全性必须选择第二种,需要服务端与前端相配合,当安全性要求不高时可采用第一种方式。

下面用的封装方法是第二种
且用到了表单验证,需要注意的是表单验证受控时需要做处理。

**

服务端签名回传,并且设置回调

**

import { Form, Upload, message, Button } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import React from 'react'
 
class AliyunOSSUpload extends React.Component {

  state = {
    OSSData: {},
  };

  async componentDidMount() {
    await this.init();
  }

  init = async () => {
    try {
      const OSSData = await mockGetOSSData();   // 后端返回接口数据

      this.setState({
        OSSData,
      });
    } catch (error) {
      message.error(error);
    }
  };

 
//   mockGetOSSData = () => ({
//     dir: 'user-dir/',
//     expire: '1577811661',
//     host: '//www.mocky.io/v2/5cc8019d300000980a055e76',
//     accessId: 'c2hhb2RhaG9uZw==',
//     policy: 'eGl4aWhhaGFrdWt1ZGFkYQ==',
//     signature: 'ZGFob25nc2hhbw==',
//   });

  onChange = ({ fileList,file }) => {
    if(file.status ==='done'){
        //上传成功之后,把文件的key,设置为表单某个字段的值16
        // (父组件)const [formobj]=ProForm.useForm()
        // formobj.setFieldsValue({'cover':filekey})  <form  form={formobj}>
        //******* !!!!!!!!一定要注意组件不能和form.item 形成受控组件,需要用div或其他包着 */
        this.props.setCoverkey=  (file.key)
        
      message.success('上传成功')
    }

    // const { onChange } = this.props;
    // console.log('Aliyun OSS:', fileList);
    // if (onChange) {
    //   onChange([...fileList]);
    // }
  };

  onRemove = file => {
    const { value, onChange } = this.props;

    const files = value.filter(v => v.url !== file.url);

    if (onChange) {
      onChange(files);
    }
  };

  getExtraData = file => {
    const { OSSData } = this.state;

    return {
      key: file.key,
      OSSAccessKeyId: OSSData.accessId,
      policy: OSSData.policy,
      Signature: OSSData.signature,
    };
  };

  beforeUpload = async file => {
    const { OSSData } = this.state;
    const expire = OSSData.expire * 1000;
     //签名过期,重新获取
    if (expire < Date.now()) {
      await this.init();
    }
    //定义放图片的目录
    const dir = 'osspic'
    const suffix = file.name.slice(file.name.lastIndexOf('.'));
    const filename = Date.now() + suffix;
    file.key = OSSData.dir + dir+filename;//额外参数中,在云存储中存储的文件key

    file.url = OSSData.host+OSSData.dir + dir+filename; //上传用于显示的内容

    return file;
  };

  render() {
    const { value } = this.props;
    const props = {
      accept:this.props.accept||'',//可接收的文件格式,如'image/*'
      name: 'file',
      fileList: value,
      action: this.state.OSSData.host,
      onChange: this.onChange,
      onRemove: this.onRemove,
      data: this.getExtraData,
      beforeUpload: this.beforeUpload,
      maxCount:1,
      listType:'picture',
    };
    return (
        // 表单验证可加<ProForm.Item name='cover'> 需要匹配验证
      <Upload {...props}>
             {...props.children}
      </Upload>
    );
  }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值