vue + axios 使用 FormData上传文设置 multipart/form-data 无效的问题

3,928 阅读1分钟

发现问题的过程

新建的工程,然后有个上传文件的需求,就按照以往的经验去搞的

  • 1、使用 post 请求,配置 config:

    headers: { 'Content-Type': 'multipart/form-data' }

  • 2、创建 FormData

       const formData = new FormData();
       formData.append(key, value); // 请求参数`
       formData.append('file', file); // 文件列表
    
  • 3、然后接口就报 500 了,但是接口用 postman 是好使的,看接口的请求参数,Content-Type 虽然是 multipart/form-data 但是缺少 boundary, 发现还是 request payload,正常来说应该 Form Data

    image.png

    然后有直接使用 xhr 进行测试发现是没问题的

    代码如下:

    if (this.fileList && this.fileList.length > 0) {
            const config = { headers: { 'Content-Type': 'multipart/form-data' } };
            const formData = new FormData();
            this.fileList.forEach(file => {
                formData.append('file', (file as unknown) as Blob);
            });
            Http.post(Urls.importSupplier, formData, config).then(res => {
                console.log(res);
            });
            // const xhr = new XMLHttpRequest();
            // xhr.open('post', '/conductcustomersupplier/importSupplier', true);
            // xhr.responseType = 'json';
            // xhr.send(formData);
            // xhr.onload = () => {
            //     if (xhr.readyState === 4 && xhr.status === 200) {
            //         const json = xhr.response;
            //     }
            // };
        }
    

    经过多方查找发现是添加了求拦截的问题 service.interceptors.response.use()

解决方法

  • 1、去掉 service.interceptors.request.use() 拦截

  • 2、重新创建一个 axios 实例,Axios.create().request(config)

    /**
       * 使用 form 表单上传文件
       * @param url 请求接口 url
       * @param params 请求参数
       * @param files 文件列表
       */
      public static uploadFiles = (() => {
          let instance: AxiosInstance | null = null;
          return (
              url: string,
              files: AnyType[] = [],
              params?: AnyType,
              config?: AxiosRequestConfig,
          ): Promise<ResOutDto> => {
              if (!instance) {
                  instance = Axios.create({ timeout: 600000 });
              }
              config = {
                  headers: { 'Content-Type': 'multipart/form-data' },
                  method: 'post',
                  params: {},
                  url: Http.getUrl(url),
                  ...config,
              };
    
              const formData = new FormData();
              if ('object' === typeof params) {
                  for (const key in params) {
                      if (Object.prototype.hasOwnProperty.call(params, key)) {
                          const value = params[key];
                          config.params[key] = value;
                          formData.append(key, value);
                      }
                  }
              }
              if (files && files.length > 0) {
                  files.forEach(file => {
                      formData.append('file', file);
                  });
              }
              config.data = formData;
              return instance.request(config);
          };
      })();
    
     Http.uploadFiles(Urls.importSupplier, this.fileList, { params: 123456}).then(
          res => {
              const { code, msg } = res;
              if (code === 200) {
                  this.visible = false;
              } else {
                  this.$message.error(msg);
              }
          },
      );
    

正确的请求如下 image.png

参考地址:blog.csdn.net/qq_41688165…