Ant Design Upload 组件上传文件到云服务器 - 七牛云、腾讯云和阿里云的分别实现

在前端项目中经常遇到上传文件的需求,ant design 作为 react 的前端框架,提供的 upload 组件为上传文件提供了很大的方便,官方提供的各种形式的上传基本上可以覆盖大多数的场景,但是对于不同的服务器平台,可能实现方式会有所不同,尤其最近使用了阿里云作为服务器上传,就需要自定义上传行为才能满足需求,因此针对不同平台文件上传的异同和 upload 组件使用中遇到的问题做一个简单总结,希望可以对遇到类似问题的小伙伴有所帮助。
首先这里大致总结了几个不同平台服务器上传方式的异同:
| 服务器平台 | 上传凭证 | 请求方式 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#customrequest。
接下来看不同的平台具体上传实现上的基本代码:
七牛云上传方式比较简单,官方提供了统一的上传地址 https://upload-z2.qiniu.com,只要获取上传凭证就可以了,如下:

文件上传的组件部分
对应的主要方法(这些方法在不同平台的上传过程中都是可用的,内部具体操作可能会有所不同):

文件上传相应方法
腾讯云和七牛云的上传方式类似,不同的是上传地址是通过请求凭证获取到的,因此组件属性中的 aciton 字段的需要通过请求获得:如下:

阿里云和腾讯云上传的不同点在于请求方式和文件格式不同,而 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

Ant Design Upload 组件上传文件到云服务器 - 七牛云、腾讯云和阿里云的分别实现的更多相关文章
- ant design for vue 上传文件
1.使用customRequest customRequest 通过覆盖默认的上传行为,可以自定义自己的上传实现 Function 定义customRequest,之前定义action行为会被覆盖,可 ...
- [自动运维]ant脚本打包,上传文件到指定服务器,并部署
1.根节点使用,表示根目录为当前目录,默认启动的target为build,项目名称为othersysm, <project basedir="." default=" ...
- 关于本地使用antd的upload组件上传文件,ngnix报错405的问题
使用阿里的ui框架antd的upload,会自动请求ngnix上面的一个路径,也就是action所在的位置,一直报错405 not allowed,后来经讨论,统一将action写成一个路径,后端对这 ...
- 使用commons-fileUpload组件上传文件
在近期的一个项目中有用到commons-fileUpload组件进行实现文件上传的功能(由于没用到框架),在使用的过程中有遇到一些问题,经过自己的琢磨也算顺利地将其解决了,在这里做个记录. 一.com ...
- React antd如何实现<Upload>组件上传附件再次上传已清除附件缓存问题。
最近在公司做React+antd的项目,遇到一个上传组件的问题,即上传附件成功后,文件展示处仍然还有之前上传附件的缓存信息,需要解决的问题是,要把上一次上传的附件缓存在上传成功或者取消后,可以进行清除 ...
- EasyUI 关于IE使用window组件上传文件
有时候IE会对使用window组件上传文件(第二次)不生效,解决方案是: 将该window每次打开的时候,使用: $('#adUploadWindow').window('refresh', 'pan ...
- 在C#客户端用HTTP上传文件到Java服务器
在C#客户端用HTTP上传文件到Java服务器 来源:http://www.cnblogs.com/AndyDai/p/5135294.html 最近在做C / S 开发,需要在C#客户端上传文件到 ...
- asp.net 服务器 上传文件到 FTP服务器
private string ftpServerIP = "服务器ip";//服务器ip private string ftpUserID = "ftp的用户名" ...
- PHP 上传文件到其他服务器
PHP 上传文件到其他服务器 标签(空格分隔): 安装Guzzle类库 **guzzle** 是发送网络请求的类库 composer安装:**composer require guzzlehttp/g ...
随机推荐
- Python中的构造函数
Python中的构造函数是__init__函数.在Python中,子类如果定义了构造函数,而没有调用父类的,那么Python不会自动调用,也就是说父类的构造函数不会执行. 比如有test.py的mod ...
- scrum立会报告+燃尽图(第二周第五次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2250 一.小组介绍 组名:杨老师粉丝群 组长:乔静玉 组员:吴奕瑶.公冶 ...
- 基础算法学习2-dp
一.算法题: 最大子阵 给定一个n×m 的矩阵 A,求A 中的一个非空子矩阵,使这个子矩阵中的元素和最大.其中,A 的子矩阵指在 A 中行和列均连续的一部分.输入格式输入的第一行包含两个整数 n,m( ...
- OOP 1.1 引用
1.1 引用 1.语法:类型名&引用名=某变量名 e.g. int &b=a; 定义:引用则等价这个变量 引用名的类型是:类型 & 注意事项: ①定义引用时,一定要将其初始化成 ...
- SGU 199 Beautiful People 二维最长递增子序列
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20885 题意: 求二维最长严格递增子序列. 题解: O(n^2) ...
- 获取Class实例的三种方式
方式一: 通过类.枚举.接口.注解.数组类型.原生类型的名称.class package com.rong.test; public class TestClass { public static ...
- windows下面安装python3遇到的没有添加到环境变量的问题
windows下面安装python3出现的问题 在官网上面下载最新版的安装包进行安装,并勾选Add Python 3.5 to PATH 安装的过程中可能会出现没有添加到PATH路径的情况 默认的安装 ...
- JavaScript常用方法(工具类的封装)
日期格式化 function formatDateTime(timeStamp) { var date = new Date(); date.setTime(timeStamp); var y = d ...
- (三)MySQL学习笔记
[Leecode]175. 组合两个表 解答:由于是组合两个表的信息,很容易想到连接查询,这里使用左连接 select p.Firstname,p.Lastname,q.City,q.State fr ...
- 51nod 1317 相似字符串对(容斥原理+思维)
题意: 称一对字符串(A,B)是相似的,当且仅当满足以下条件: (1)字符串A和B都恰好包含N个字符: (2)A和B串中的每个字符都是小写字母的前k个字符,即A.B中只可能出现'a','b','c', ...