Ant Design Upload 組件上傳文件到雲服務器 - 七牛雲、騰訊雲和阿里雲的分別實現

在前端項目中常常遇到上傳文件的需求,ant design 做爲 react 的前端框架,提供的 upload 組件爲上傳文件提供了很大的方便,官方提供的各類形式的上傳基本上能夠覆蓋大多數的場景,可是對於不一樣的服務器平臺,可能實現方式會有所不一樣,尤爲最近使用了阿里雲做爲服務器上傳,就須要自定義上傳行爲才能知足需求,所以針對不一樣平臺文件上傳的異同和 upload 組件使用中遇到的問題作一個簡單總結,但願能夠對遇到相似問題的小夥伴有所幫助。html

首先這裏大體總結了幾個不一樣平臺服務器上傳方式的異同:前端

    服務器平臺          上傳憑證            請求方式 method         文件格式 content-type      
七牛雲 key、token POST  multipart/form-data
騰雲雲 key、url POST  multipart/form-data
阿里雲 key、url PUT application/octet-stream

 

 

 

 

 

upload 組件默認提供的請求方式是POST,而且文件的提交類型是 form-data 格式,所以使用 upload 組件能夠直接上傳文件到七牛雲和騰訊雲,可是在上傳到阿里雲的時候,就須要對上傳操做進行配置(須要吐槽一句,一樣是自家的產品,爲何請求方式不統一),爲此官方提供了 customRequest 這個 api 而且FAQ中提供了參考文檔:https://github.com/react-component/upload#customrequestvue

接下來看不一樣的平臺具體上傳實現上的基本代碼:react

七牛雲上傳方式比較簡單,官方提供了統一的上傳地址 https://upload-z2.qiniu.com,只要獲取上傳憑證就能夠了,以下:ios

                  文件上傳的組件部分git

對應的主要方法(這些方法在不一樣平臺的上傳過程當中都是可用的,內部具體操做可能會有所不一樣):github

                  文件上傳相應方法axios

騰訊雲和七牛雲的上傳方式相似,不一樣的是上傳地址是經過請求憑證獲取到的,所以組件屬性中的 aciton 字段的須要經過請求得到:以下:segmentfault

阿里雲和騰訊雲上傳的不一樣點在於請求方式和文件格式不一樣,而 upload 組件默認屬性不支持對應的格式,所以須要自定義上傳行爲,具體實現以下:後端

import React, { PureComponent } from 'react'; import { Upload, Icon, message } from 'antd'; import apis from '@/services/api'; import axios from 'axios'; class Uploader extends PureComponent { state = { key: '', url: '', imageUrl: '', } // 這裏能夠作上傳以前的操做,好比文件大小的校驗等
  beforeUpload = async (file) => { const res = await this.fetchUploadToken(); return res; } // 獲取上傳憑證
  fetchUploadToken = async () => { const params = { quantity: 1, module: 3, fileType: 1, }; const res = await apis.fileSign(params); const { d, m } = res; if (m === 'success') { const { key, url } = d.l[0]; this.setState({ key, url }); return true; } else { return false; } } render() { const { imageUrl, url, key } = this.state; const that = this; const uploadProps = { name: 'file', showUploadList: false, multiple: false, accept: '.png, .jpg, .jpeg, .gif', action: url, beforeUpload: that.beforeUpload, // 這裏須要指定文件上傳的content-type
 headers: { 'Content-Type': 'application/octet-stream', }, // 自定文件上傳的方法,覆蓋組件的 onChange 方法,能夠定義上傳不一樣階段的行爲(由 axios 默認提供)
 onStart(file) { console.log('onStart', file, file.name); }, onSuccess(ret, file) { console.log('onSuccess', ret, file); that.props.getData(key); }, onProgress({ percent }, file) { console.log('onProgress', `${percent}%`, file.name); }, onError(err) { console.log('onError', err); }, customRequest({ action, file, headers, onError, onProgress, onSuccess, withCredentials, }) { // 使用 FileReader 將上傳的文件轉換成二進制流,知足 'application/octet-stream' 格式的要求
        const reader = new FileReader(); reader.readAsArrayBuffer(file); let fileData = null; reader.onload = (e) => { // 在文件讀取結束後執行的操做
          fileData = e.target.result; // 使用 axios 進行文件上傳的請求
 axios.put(action, fileData, { withCredentials, headers, onUploadProgress: ({ total, loaded }) => { // 進行上傳進度輸出,更加直觀
              onProgress({ percent: Math.round(loaded / total * 100).toFixed(2) }, file); }, }).then(response => { onSuccess(response, file); }) .catch(onError); }; return { abort() { console.log('upload progress is aborted.'); }, }; }, }; return ( <div>
        <Upload {...uploadProps}> { imageUrl ? <img src={imageUrl} /> : <Icon type='plus' /> } </Upload>
      </div>
 ); } } export default Uploader;

使用如上 PUT 請求上傳文件,在瀏覽器中打印信息格式以下:

 

總結:圖片上傳一直是前端使人頭疼的問題,不一樣的服務器平臺對請求方式和文件格式可能有不一樣的要求,所以在上傳以前須要作對應的文件處理,並且由於環境不一樣,還須要和後端合做處理跨域的問題,儘管不少優秀的組件已經提供了響應的處理方法,可是若是對組件實現原理和api不夠了解,可能依舊沒法實現一些具體的功能,因此在實現文件上傳的時候,須要多研究,多總結,針對遇到的問題要及時記錄,避免再次踩坑。

 

【參考資料】:

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

vue前端上傳文件到阿里雲oss的兩種方式,put文件流上傳,multipartUpload直接上傳

前端上傳文件至阿里雲

FileReader - Web API 接口參考 | MDN

 

相關文章
相關標籤/搜索