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下引入,(这里文件内容,稍后复制到最底下,不支持上传文件)         页面上:           

---------------------------这个是点击选择文件的                                                                                                                  浏览                                                                                            -----------------------------  这个是回填文件名称                                                                                                                                                                                                                                     --------------------------------这个是真正意义上的上传                                                                                                   上传清单                                                                       


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();

  }

});

你可能感兴趣的:(2020-10-30 上传文件给后台)