【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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容