【React】React项目使用<Upload>或者原生方法实现上传

由于项目中的几次需求都涉及到了上传文件,也尝试了antd封装的不同版本的<Upload>组件和原生的方法,在此特做一下整理总结,分享出来,大家可以参考一下

前言:对于文件的上传不同的公司交互不同,其实主要分为两种情况:
第一种:上传的时候请求接口,即文件直接传到服务器上
第二种:上传文件的时候不请求接口,直接上传,然后再点击其他按钮的时候请求接口一起传入服务器上
上传的时候请求接口业务需求:直接上传请求接口后接口返回一个路径,然后前台在利用这个路径作进一步处理(如下图),我需要上传的时候请求接口拿到后台返回给我的url,然后拿出来放到营业执照中显示出来
19_11_37__12_06_2018.jpg
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>
)
上传的时候不请求接口业务需求:上传两张照片做比对,如下图
屏幕快照 2019-02-25 下午1.51.53.png
方法一:用原生方法实现 参考我发在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;
具体可以参考我发在github上的文件 https://github.com/topvae/upload
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容