簡介
關於上傳到S3,本文服務模組使用的是‘aws-sdk’ putObject()上傳。UI模組使用的是antd中的upload元件,在使用antd元件的時候發現官方提供的上傳方式有兩種:
- 使用路徑上傳,antd中有一個屬性action需要上傳到的地址。
- 使用自定義上傳,antd中的customRequest。 本文選用的是第二種,自定義上傳會覆蓋元件預設的上傳行為,所以我們需要去定義progress、onSuccess、onError。 本文會使用到的技術:React,Rxjs,採用TSLint校驗。
先看簡單的dom模組
不多說直接上程式碼,一個簡單的自定義上傳。
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'上傳 服務模組
- 首先需要對上傳進行配置,以下是一個對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;
};
複製程式碼
- 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/
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
作者資訊:寧文飛,人和未來大資料前端工程師