React antdesign upload组件自定义上传到S3

简介

关于上传到S3,本文服务模块使用的是‘aws-sdk’ putObject()上传。UI模块使用的是antd中的upload组件,在使用antd组件的时候发现官方提供的上传方式有两种:javascript

  1. 使用路径上传,antd中有一个属性action须要上传到的地址。
  2. 使用自定义上传,antd中的customRequest。 本文选用的是第二种,自定义上传会覆盖组件默认的上传行为,因此咱们须要去定义progress、onSuccess、onError。 本文会使用到的技术:React,Rxjs,采用TSLint校验。

先看简单的dom模块

很少说直接上代码,一个简单的自定义上传。html

import React from 'react';
import { Subject } from 'rxjs';
import { Upload } from "antd";
import {IS3Config, Upload$ } from "../../../core/services/s3service";

interface IParam {
  onProgress: ({ }, f: UploadFile) => void;
  onSuccess: () => void;
  onError: () => void;
  file: UploadFile & { webkitRelativePath: string };
}
export default class UploadComponent extends React.Component {
  public S3token: IS3Config  = {}; // 您的S3临时令牌
  public bucket: string = ''; // 您要上传到的bucket名字
  public key: string = ''; // bucket下面的路径
  private upload = (param: IParam) => {
    Upload$(this.S3token, this.bucket, this.key, param).subscribe(
        () => console.log('成功'),
        () => console.log('失败'),
    );
  }
  public render () {
    return (
      <Upload customRequest={this.upload}> <Button> <Icon type="upload" /> Upload </Button> </Upload> ); } } 复制代码

'aws-sdk'上传 服务模块

  1. 首先须要对上传进行配置,如下是一个对S3进行配置的函数。 这个函数中须要您的S3临时令牌,令牌须要有对S3进行操做的权限。
// s3service.tsx
// 引入模块
import { Subject } from 'rxjs';
import { config, S3, AWSError } from 'aws-sdk';
import { PutObjectOutput} from '../../../node_modules/aws-sdk/clients/s3';
import { UploadFile } from '../../../node_modules/antd/lib/upload/interface';
// 配置S3的接口
export interface IS3Config {
  AccessKeyId?: '';
  SecretAccessKey?: '';
  SessionToken?: '';
}
// 对S3进行配置
export const createS3 = (cfg: IS3Config) => {
  const setting = { //您的S3临时令牌
    accessKeyId: cfg.AccessKeyId,
    secretAccessKey: cfg.SecretAccessKey,
    sessionToken: cfg.SessionToken,
  };
  config.update(setting);
  config.region = "us-east-1";

  const s3 = new S3({
    apiVersion: '2006-03-01',
  });
  return s3;
};

复制代码
  1. putObject 上传文件及自定义progress、success、error
interface IUpload {
  onProgress?: ({ }, f: UploadFile) => void; // 须要重写的antd的progress函数
  onSuccess?: () => void; // antd中progress百分百时的成功函数
  file: UploadFile; // 上传失败的progress函数
  onError: () => void;
}
export const Upload$ = (s3Config: IS3Config, bucket: string, key: string, body: IUpload): Subject<PutObjectOutput> => {
  const s3 = createS3(s3Config); //传入您的S3令牌
  const s3subject = new Subject(); //建立一个Subject主体
  s3.putObject( // s3上面的putObject方法 第一个参数是一个对象,第二个参数是一个函数,函数有两个值,1.表示上传失败,2.表示上传成功
    {
      Body: body.file, // 是文件类型
      Bucket: bucket, // 对应S3上的bucket
      Key: key, // 须要上传到的路径
    },
    (err: AWSError, resp: PutObjectOutput) => {
      if (err) {
        log(err);
        s3subject.error(err); // 上传失败时调用
      } else {
        s3subject.next(resp); // 上传成功时调用
      }
    }).on('httpUploadProgress', (progress) => { // 上传S3时‘httpUploadProgress’函数里能够定义progress
      const percent = 100 * progress.loaded / progress.total;
      // https://github.com/react-component/upload/blob/master/examples/customRequest.js onProgress 第一个参数是进度条的值,第二个参数是当前上传的文件 
      // body.onProgress 是antd中的onProgress 重写的progress
      body.onProgress ? body.onProgress({ percent }, body.file) : void 0;
      if (percent === 100 && body.onSuccess) body.onSuccess(); // 上传到百分百时调用 antd中的onSuccess 
    }).on('httpError', (err) => {
      if (err && body.onError) {
        log(err);
        body.onError();
        s3subject.error(err);
      }
    });
  return s3subject;
};
复制代码

感谢https://github.com/yalishizhude的指导

参考文献

https://github.com/react-component/upload/blob/master/examples/customRequest.js前端

https://ant.design/components/upload-cn/java

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-propertynode

原文连接:tech.gtxlab.com/upload.htmlreact


做者信息:宁文飞,人和将来大数据前端工程师git

相关文章
相关标签/搜索