Ant Design 使用Upload組件默認方式上傳圖片到阿里雲OSS

背景

近來作了一個管理後臺,採用的AntDesignPro腳手架,阿里版的React全家桶,包含Ant Design組件庫,Dva狀態管理,權限模塊,國際化,主題定製等等稱成熟的解決方案,固然這不是今天要將的重點。前端

今天要談論的是使用Upload默認方式上傳到OSS,爲啥要用默認的方式上傳呢?react

No reason ! Why not !!web

正文

直接上代碼,試試代碼自解釋:bash

import CryptoJS from 'crypto-js';
import Base64 from 'base-64';

...

const uploadButton = (
   <div>
     <Icon type={payImgLoading ? 'loading' : 'plus'} />
     <div className="ant-upload-text">Upload</div>
   </div>
 );
 
...

<Upload
  action="http://xxxx.oss-cn-shanghai.aliyuncs.com"
  accept="image/*"
  listType="picture-card"
  className="avatar-uploader"
  showUploadList={false}
  beforeUpload={this.beforeUpload}
  onChange={this.handleChange}
  data={{
    key: todayKey + "/${filename}",
    policy: policyBase64,
    OSSAccessKeyId: accessKeyId,
    success_action_status: 200,
    signature,
  }}
>
  {
     payImgUrl ? 
     <img 
        src={imgUrl} 
        alt="avatar" 
        style={{ width: '100%' }} 
     /> : 
     uploadButton
     
  }
</Upload>

複製代碼

以上代碼重點關注Upload組件的action屬性和data屬性,一個是圖片上傳接口地址,固然能夠直接是 OSS 對象存儲地址; 而核心在data屬性上:antd

  • key: 文件路徑採用:日期文件夾 + 文件名

須要注意的是後面的 "/${filename}",這裏不是反引號,總體是字符串,filename是形參,不能填入真實文件名;curl

  • policy: policyBase64
const policyText = {
  "expiration": "2028-01-01T12:00:00.000Z", // 設置該Policy的失效時間
  "conditions": [
    ["content-length-range", 0, 1048576000] // 設置上傳文件的大小限制
  ]
};
const policyBase64 = Base64.encode(JSON.stringify(policyText))
複製代碼
  • OSSAccessKeyId: 阿里雲OSS keyid
  • success_action_status:200
  • signature: 建議採用後臺簽名,下面是前端簽名方法,accessSecret是阿里雲OSS祕鑰
const bytes = CryptoJS.HmacSHA1(policyBase64, accessSecret, { asBytes: true });
const signature = bytes.toString(CryptoJS.enc.Base64); 
複製代碼

上面使用到兩個加密庫編輯器

import CryptoJS from 'crypto-js';// "base-64": "^0.1.0"
import Base64 from 'base-64';//  "crypto-js": "^3.1.9-1"
複製代碼

今天這個編輯器總是自動滾動,不囉嗦了,在配置中遇到問題請留言吧...ide

福利,附上完整代碼

/* eslint-disable no-template-curly-in-string */

import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';
import CryptoJS from 'crypto-js';
import Base64 from 'base-64';
import {
  Card, Form, Input, Divider, Icon, Upload, message, Button,
  Table, Modal, InputNumber, Select, Popconfirm
} from 'antd';

const todayKey = moment().format('YYYYMMDD');
const host = "http://xxxx.oss-cn-shanghai.aliyuncs.com";
const accessKeyId = "xxxxx";
const accessSecret = "xxxxxx";
const policyText = {
  "expiration": "2028-01-01T12:00:00.000Z", // 設置該Policy的失效時間,
  "conditions": [
    ["content-length-range", 0, 1048576000] // 設置上傳文件的大小限制
  ]
};
const policyBase64 = Base64.encode(JSON.stringify(policyText))
const bytes = CryptoJS.HmacSHA1(policyBase64, accessSecret, { asBytes: true });
const signature = bytes.toString(CryptoJS.enc.Base64); 


@Form.create()
@connect(({loading, usermanage }) => ({
  userList: usermanage.userList,
  loading: loading.models.usermanage,
}))
class TableList extends PureComponent {

  state = {
    payImgLoading: false,
    payImgUrl: ''
  };
  

  beforeUpload = (file) => {
    // 檢查圖片類型
    const isJPG = file.type === 'image/jpeg';
    const isPNG = file.type === 'image/png';
    const isBMP = file.type === 'image/bmp';
    const isGIF = file.type === 'image/gif';
    const isWEBP = file.type === 'image/webp';
    const isPic = isJPG || isPNG || isBMP || isGIF || isWEBP;
    if (!isPic) {
      message.error('請上傳圖片');
      return;
    }
    const isLt5M = file.size / 1024 / 1024 < 5;
    if (!isLt5M) {
      message.error('上傳圖片必須小於 5MB!');
      return;
    }
    return isPic&&isLt5M;
  }

  handleChange = ({ file }) => {
    if (file.status === 'uploading') {
      this.setState({ payImgLoading: true });
      return;
    }
    if (file.status === 'done') {
      this.setState({
        payImgUrl: `${host}/${todayKey}/${file.name}`,
        payImgLoading: false,
      });
    }
  }


  render() {
    
    const uploadButton = (
      <div>
        <Icon type={payImgLoading ? 'loading' : 'plus'} />
        <div className="ant-upload-text">Upload</div>
      </div>
    );
  
    return (
        <Upload
           action={host}
           accept="image/*"
           listType="picture-card"
           className="avatar-uploader"
           showUploadList={false}
           beforeUpload={this.beforeUpload}
           onChange={this.handleChange}
           data={{
             key: todayKey + "/${filename}",
             policy: policyBase64,
             OSSAccessKeyId: accessKeyId,
             success_action_status: 200,
             signature,
           }}
        >
           {
               payImgUrl ? 
               <img src={payImgUrl} alt="avatar" style={{ width: '100%' }} /> :
               uploadButton   
           }
        </Upload>    
    );
  }
}


複製代碼
相關文章
相關標籤/搜索