由于项目中的几次需求都涉及到了上传文件,也尝试了antd封装的不同版本的<Upload>组件和原生的方法,在此特做一下整理总结,分享出来,大家可以参考一下
前言:对于文件的上传不同的公司交互不同,其实主要分为两种情况:
第一种:上传的时候请求接口,即文件直接传到服务器上
第二种:上传文件的时候不请求接口,直接上传,然后再点击其他按钮的时候请求接口一起传入服务器上
上传的时候请求接口业务需求:直接上传请求接口后接口返回一个路径,然后前台在利用这个路径作进一步处理(如下图),我需要上传的时候请求接口拿到后台返回给我的url,然后拿出来放到营业执照中显示出来
import {Upload} from 'antd';
export default class Customer extends React.Component{
this.state={
organCertUrl:"",//用来存放图片地址的对象
}
render(){
//------------------------------------定义上传图片的参数----------------------------------------
const $this=this
const props = {
ref:"upload",
action: '/safemgmt/api/custom/uploadOrganPic', //这块是将后台给你的接口地址需要改一下你自己的交互地址
listType: 'picture',
className: 'upload-list-inline',
onChange({ file, fileList }) {//file,和fileList是组件自带的参数,根据你上面赋值过去的接口给你返回的内容,file是个对象,fileList是个数组,其实file对象就相当于你用axios方法返回的response对象差不多啦~
if (file.status === 'done') {
$this.setState({
organCertUrl:file.response.result,//前面是我的存放地址的对象
})
}
}
}
}
}
return(
<div>
//..........中间的其他内容省略,下面是上传组件内容
<div key={Math.random()}>
<Upload {...props} defaultFileList={this.state.fileList}>
<Button>
<Icon type="upload" onClick={this.upLoadImg}/> 上传
</Button>
</Upload>
</div>
</div>
)
上传的时候不请求接口业务需求:上传两张照片做比对,如下图
方法一:用原生方法实现 参考我发在github上的App.js文件 https://github.com/topvae/upload
import React, { Component } from 'react';
import $ from 'jquery';
import { Input, Form, message} from 'antd';
import 'antd/dist/antd.css';
import './App.css';
class App extends Component {
state={
fileList:[],
file1:{},
fileList2:[],
file2:{},
imageUrl:'',
input1:{},
input2:{},
resdata:"",
uploading: false //
}
inputfile =()=> {
let file1 = document.querySelector('#input').files[0];
if(file1){
var reader = new FileReader();
// 图片文件转换为base64
reader.readAsDataURL(file1);
reader.onload = function(){
// 显示图片
document.getElementById("file1_img").src = this.result;
}
}
this.setState({
file1:file1
})
}
inputfile2 =()=> {
let file2 = document.querySelector('#input2').files[0];
if(file2){
var reader = new FileReader();
// 图片文件转换为base64
reader.readAsDataURL(file2);
reader.onload = function(){
// 显示图片
document.getElementById("file2_img").src = this.result;
}
}
this.setState({
file2:file2
})
}
comparePic=()=>{
let _this = this
//点击的时候就一直是加载中
_this.setState({
uploading: true,
});
var $data = new FormData($("#form_test")[0]);
$.ajax({
url:"/safe/face/faceCompareForSavePic",
method:'post',
data:$data,
contentType: false, //必须写这个,防止和form中的content-type起冲突
processData: false, //解决illegal invocation报错的问题
accepts: {
mycustomtype: 'application/x-some-custom-type'
},
// dataType: "multipart/form-data",
success:function(res){
if(res.code === 0){
_this.setState({
resdata:res.data.similarity,
uploading: false, //成功后不加载了
},()=>{ message.success(`相似度为${_this.state.resdata}%`);})
}else{
_this.setState({
resdata:res.msg,
uploading: false
},()=>{ message.error(_this.state.resdata);})
}
}
});
}
render() {
return (
<div className="homepage">
<Form
id="form_test"
onSubmit={this.comparePic}
target="nm_iframe"
method="post"
enctype="multipart/form-data"
>
<iframe id="id_iframe" name="nm_iframe" style={{display:'none'}}></iframe>
<div id="img_div1">
<img id="file1_img" src="" alt=""/>
</div>
<div id="input_div1">
选择文件
<Input type="file" id="input" name="file1" onChange={this.inputfile} ></Input>
</div>
<div id="img_div2">
<img id="file2_img" src="" alt=""/>
</div>
<div id="input_div2">
选择文件
<Input type="file" id="input2" name="file2" onChange={this.inputfile2}></Input>
</div>
<div>
<Input id="submit" type="submit" name="submit" value={this.state.uploading ? '加载中...' : '比对照片'}/>
</div>
</Form>
</div>
);
}
}
//注意,Input中的name代表的是传给后台的参数 enctype="multipart/form-data"是前后台约定的类型
export default App;
方法二:用antd的<Upload>组件的手动上传的代码(参考upload组件中的手动上传的例子)可以参考我发在github上的demo.js文件 https://github.com/topvae/upload
//上传的时候不请求接口,参考antd官网的手动上传方法,需要提前npm安装reqwest npm install reqwest
import React from 'react';
import {
Upload, Button, Icon, message,
} from 'antd';
import 'antd/dist/antd.css';
import reqwest from 'reqwest'; //这块要安装一下reqwest npm install reqwest
class Demo extends React.Component {
state = {
fileList: [],
uploading: false,
}
handleUpload = () => {
const { fileList } = this.state;
const formData = new FormData();
formData.append('file1', fileList[0]); //注意第一个参数是传给后台的参数名字,我的项目中叫file1
formData.append('file2', fileList[1]); //注意第一个参数是传给后台的参数名字,我的项目中叫file2
this.setState({
uploading: true,
});
// You can use any AJAX library you like
reqwest({
url: '/safe/face/faceCompareForSavePic', //这块是你项目的接口
method: 'post',
processData: false,
data: formData,
success: () => {
this.setState({
fileList,
uploading: false,
});
message.success('upload successfully.');
},
error: () => {
this.setState({
uploading: false,
});
message.error('upload failed.');
},
});
}
render() {
const { uploading, fileList } = this.state;
const props = {
onRemove: (file) => {
this.setState((state) => {
const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice();
newFileList.splice(index, 1);
return {
fileList: newFileList,
};
});
},
beforeUpload: (file) => {
this.setState(state => ({
fileList: [...state.fileList, file],
}));
return false;
},
fileList,
};
return (
<div>
<Upload {...props}>
<Button>
<Icon type="upload" /> Select File
</Button>
</Upload>
<Button
type="primary"
onClick={this.handleUpload}
disabled={fileList.length === 0}
loading={uploading}
style={{ marginTop: 16 }}
>
{uploading ? 'Uploading' : 'Start Upload' }
</Button>
</div>
);
}
}
export default Demo;