2020-10-30 上传文件给后台

背景:点击【浏览】按钮选择一个文件,将文件名获取到展示在页面上,用户可以随意更改选择的文件,点击【上传文件】按钮将已上传的文件上送给后台

入坑1:根据以上背景需求,使用ant design upload上传组件,该组件的原理默认是选择文件即上传,当然为了满足项目需求,可以在上传的beforeUpload 函数里给return false,只用于拦截上传行为,不会阻止文件进入上传列表(原因)。如果需要阻止列表展现,可以参照此例配合 onChange 进行实现。看一下图例


在上述图中beforeUpload中禁止默认上传,先存一下上传的文件,在点击最后上传的按钮时,在将文件上送给后端,图例如下:


上图框①中是将文件进行二进制转化,必须要这样转换一下,框②是因为上送给后台是,前端发送过去的请求头是”Content-Type:application/json; charset=utf-8 ,在后端就会报这样的错”Current request is not a multipart request“意思就是说前端猿媛上送的不是一个文件格式,后台拦截了,于是乎,我在reqwest请求中加上 contentType:'multipart/form-data; boundary=----WebKitFormBoundaryjktt63FyovoiTw9T',或者 contentType:'multipart/form-data',尝试上送,依然在请求头request header中显示Content-Type:

application/json; charset=utf-8,就是说前端设置的不生效,到了此处很无解纳闷,不能重设请求头吗(此处一万个问号❓);再换一种思路,设置headers: { 'Content-Type': 'multipart/form-data',},然后后端报了另一种错误”不允许修改header头部”,再次崩溃😩!!!!,不清楚reqwest这里怎末就不识别上传的是个文件,此处是个大难题?未解😭

方案:

工作还是要做的,毕竟需求是老大嘛,于是请教了一位大神,用了另一种上传组件【WebUploader】引入WebUploader的js放到component下引入,(这里文件内容,稍后复制到最底下,简书不支持上传文件)         页面上:           

---------------------------这个是点击选择文件的                                                                                                                  <Button tye="primary" id="upload">浏览</Button>                                                                                            -----------------------------  这个是回填文件名称                                                                                                  <Input    placeholder="选择要上传的文件"   disabled   className={suse.uploadInput}     defaultValue={[]}      value={this.state.fileName} />                                                                                                                                   --------------------------------这个是真正意义上的上传                                                                                                   <Button type="primary" onClick={this.uploadFile}>上传清单 </Button>                                                                      


js:

  componentDidMount() {

    this.webUuploader();// 加载绑定上传函数

  }

  webUuploader() {

    let self = this;

    setTimeout(() => {

      self.uploader = WebUploader.create({

        pick: '#upload',//这个要给绑定事件的对象,

        accept: {

          title: 'files',

          extensions: 'xls,xlsx',//此处可以修改,要求上传文件什么类型

          mimeTypes: 'xls,xlsx'//此处可以修改,要求上传文件什么类型

        },

        scenario: 'smartPolicy',

        threads: 1,

        formData: { 'column': 6 },//这里可以额外上送想上送的参数

        multiple: false,

        server: configs.host + UploadExcel,

        // fileSizeLimit: 10 * 1024 * 1024,

        auto: false,//设置成false是不自动上传后台,true的话就是选择文件即上传

        uploaded: (res, file) => {//这里是上传给后台返回的成功与否信息

          if (res.responseCode == '000000') {alert('客户名单新增成功')} else { alert('客户名单新增失败') }

        }

      });

      self.uploader.on('filesQueued', (file) => {

        self.setState({

          fileName: file[0].name,//获取上传的文件名

        });

      });

      self.uploader.on('uploadStart', (file, co) => {

        self.setState({

          fileName: file.name,

        }, () => {

          console.log('文件名1', self.state.fileName)

        });

      });

      // 自定义上传参数

      self.uploader.on('uploadBeforeSend', (object, data, header) => {

        header.acceptLanguage = 'zh_CN';

      });

    }, 100);

  };


以下是WebUploader的js内容:

// import './index.scss';

import WebUploader from 'webuploader';

import CFNetwork, {

  uploadFileData

} from 'utils/network/CFNetwork.js';

import api from 'configs';

// 异常提示,可以使用 global.UtilsWebuploadorIndexErrorMsg 重新定义

global.UtilsWebuploadorIndexErrorMsg = {

  // 默认报错

  error: '上传出错,请检查后重新上传!',

  // 上传格式错误

  type: '上传文件格式错误!',

  // 文件太大

  big: '上传文件太大'

};

// webuploader 辅助类,使用 create 创建 webuploader

export default {

  /**

   * 创建 webuploader

   * @param options 配置可以参照 webuploader,也可以参考注释的代码

   * @param interfaces 接口

      {

        upload: 上传

      }

   */

  create: (options, interfaces, host) => {

    host = host || api.host;

    if (interfaces == null) {

      if (!/\/$/.test(host)) {

        host = host + '/';

      }

      interfaces = {

        upload: host + 'file/upload'

      };

    }

    options = Object.assign({

      // 文件上传

      server: interfaces.upload,

      // 一旦有文件自动上传

      auto: true,

      // 在上传当前文件时,准备好下一个文件

      prepareNextFile: true,

      // 可以重复上传

      duplicate: true,

      // [function] 上传前判断是否可以上传

      beforeFileQueued: null,

      // [function] 上传后执行事件

      uploaded: null,

      // 多文件上传

      multiple: true,

      // 上传参数 key 值

      uploadKeys: ['ext', 'name', 'fileMd5'],

      // 应用场景

      scenario: null,

      // 0=增量 1=全量替换 目前只用于敏感词。

      flagIncrement: 0,

      // 敏感词时,未必填

      robotId: null,

      // 禁用拖拽功能

      // dnd: '#dndVideo',

      // 允许的格式

      // accept: {

      //   title: 'video',

      //   extensions: 'mp4',

      //   mimeTypes: 'audio/mp4, video/mp4'

      // },

      // 单个文件最大字节 100MB

      // fileSingleSizeLimit: 100 * 1024 * 1024,

      // 文件最大字节

      // fileSizeLimit: 1,

    }, options);

    options.pick = {

      id: options.pick,

      multiple: options.multiple

    };

    options.interfaces = interfaces;

    let uploader = WebUploader.create(options);

    bindWebuploadEvent(uploader, options);

    return uploader;

  }

};

// 创建一个 webuploader 用于自己操作事件

export function create(options) {

  return WebUploader.create(options);

};

// 绑定处理事件

function bindWebuploadEvent(uploader, options) {

  let uploadedTimer = null;

  let {

    scenario,

    flagIncrement,

    robotId

  } = options;

  uploader.on('uploadBeforeSend', (result, data) => {

    let deferred = WebUploader.Deferred();

    let name = result.file.name;

    let ext = name.substring(name.lastIndexOf('.') + 1);

    let uploadKeys = uploader.options.uploadKeys;

    let params = {

      scenario,

      flagIncrement,

      robotId

    };

    params[uploadKeys[0]] = ext;

    params[uploadKeys[1]] = name;

    params[uploadKeys[2]] = result.file.fileMd5;

    Object.assign(data, uploadFileData(params));

    return deferred.promise();

  });

  // 文件上传结束,通知合并分块

  uploader.on('uploadSuccess', (file, response) => {

    uploader.options.uploaded && uploader.options.uploaded(response, file);

  });

  // 错误的处理

  uploader.on('error', (type, size, file) => {

    let msg = global.UtilsWebuploadorIndexErrorMsg.error;

    if (type == 'Q_TYPE_DENIED') {

      msg = global.UtilsWebuploadorIndexErrorMsg.type;

    } else if (type == 'Q_EXCEED_SIZE_LIMIT') {

      msg = global.UtilsWebuploadorIndexErrorMsg.big;

    } else if (type == 'F_EXCEED_SIZE') {

      msg = global.UtilsWebuploadorIndexErrorMsg.big;

    }

    uploader.options.uploaded && uploader.options.uploaded({

      code: -2,

      msg

    });

  });

  // 上传失败

  uploader.on('uploadError', (file) => {

    // console.log(file);

    uploader.options.uploaded && uploader.options.uploaded({

      code: -1,

      msg: global.UtilsWebuploadorIndexErrorMsg.error

    }, file);

  });

  // 全部文件执行完毕

  uploader.on('uploadFinished', () => {

    if (!uploadedTimer) {

      uploadedTimer = setInterval(() => {

        clearInterval(uploadedTimer);

        uploadedTimer = null;

        // uploader.reset();

      }, 300);

    }

  });

};

WebUploader.Uploader.register({

  'before-send-file': 'beforeSendFile'

}, {

  beforeSendFile: function(file) {

    let deferred = WebUploader.Deferred();

    (new WebUploader.Uploader()).md5File(file).then(value => {

      file.fileMd5 = value;

      deferred.resolve();

    });

    return deferred.promise();

  }

});

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

推荐阅读更多精彩内容

  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,518评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,561评论 0 11
  • 可爱进取,孤独成精。努力飞翔,天堂翱翔。战争美好,孤独进取。胆大飞翔,成就辉煌。努力进取,遥望,和谐家园。可爱游走...
    赵原野阅读 2,724评论 1 1
  • 在妖界我有个名头叫胡百晓,无论是何事,只要找到胡百晓即可有解决的办法。因为是只狐狸大家以讹传讹叫我“倾城百晓”,...
    猫九0110阅读 3,259评论 7 3