formData手动上传问题前端如何传递后端如何接收


一. 前言

参考文章:
解决Current request is not a multipart request
axios上传文件错误:Current request is not a multipart reques


二. 问题描述

之前使用el-upload使用默认action表单提交.前端默认content-type为multipart/form-data.没有问题. 后期渐进式优化.修改为axios+formdata传递内容.

Current request is not a multipart request
这个错误是因为后端读取MultipartFile 类型数据时,对申请头的类型进行了一个判断,他只识别 multipart 开头的 Content-Type。所以我们需要修改headers 的 Content-Type。但是手动添加headers会产生第二个错误。所以建议使用formdata 的方式.
参数为formdata 时,浏览器会自动添加一个标准的headers。
在这里插入图片描述
在这里插入图片描述
上传代码
在这里插入图片描述

提交post封装请求
在这里插入图片描述

三.前端正确解决方式

前端上传文件总共有两种方式.通过axios-formData和axios传递.
axios可以通过序列化纯字符串传递.但是缺乏这样的经验.后端接收比较麻烦.因此推荐axios-formData

          <el-form-item label="上传简历">
            <el-upload
                ref="recruitRef"
                class="upload-demo"
                drag
                action="#"
                :auto-upload="false"
                :on-change="handleChange"
                limit="1"
            >
              <el-icon class="el-icon--upload">
                <upload-filled/>
              </el-icon>
              <div class="el-upload__text">
                拖拽 或 <em>点击上传</em>
              </div>
              <template #tip>
                <div class="el-upload__tip">
                  .pdf 文件大小 ≤ 500kb
                </div>
              </template>
            </el-upload>
          </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="postResumeForm()">投递</el-button>
      </el-form-item>
const resumeForm = reactive({
    
    
  name: '',
  phone: '',
  email: '',
  experience: '',
  education: '',
  position: router.currentRoute.value.params.position
})

const recruitRef = ref()

let formData = new FormData()

function handleChange(uploadFile, uploadFiles) {
    
    
  if (!verifyBeforeUpload(uploadFile)) {
    
    
    removeFile()
    return
  }
  formData.append("file", uploadFile)
}

function removeFile() {
    
    
  if (recruitRef.value) {
    
    
    formData = new FormData()
    recruitRef.value.clearFiles()
  }
}

export const ACCEPTED_EXTENSIONS = ['pdf'];

// 单文件大小校验
function verifyFileSize(file) {
    
    
    if (file) {
    
    
        let fileSize = file.size;
        let fileMaxSize = 1024 * 500;//500kb
        if (fileSize > fileMaxSize) {
    
    
            ElMessage.error("文件不能大于500kb!");
            file.value = "";
            return false;
        } else if (fileSize <= 0) {
    
    
            ElMessage.error("文件不能为0kb!");
            file.value = "";
            return false;
        }
        return true
    }
    ElMessage.error("必须传递文件!")
    return false;

}

// 校验文件格式和大小
export function verifyBeforeUpload(file) {
    
    
    // 格式
    const extension = file.name.split('.').pop().toLowerCase();
    console.log(extension)
    if (!ACCEPTED_EXTENSIONS.includes(extension)) {
    
    
        ElMessage.error('仅支持 pdf 格式的文件');
        return false;
    }
    // 大小
    return verifyFileSize(file);
}


function postResumeForm() {
    
    
  ElMessageBox.confirm('确认提交?提交后仅能修改一次', '提示', {
    
    
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(async () => {
    
    
    if (formData === null || formData === undefined) {
    
    
      ElMessage.info("必须递交简历信息!")
      return
    }
    for (let key in resumeForm) {
    
    
      formData.append(key,resumeForm[key])
    }
    let res = await reqPostResumeForm(formData)
    if (res.code !== 200) {
    
    
      ElMessage.error("简历投递失败")
      return
    }
    await ElMessageBox.alert("简历投递成功! 3-7个工作日内,您将收到回复", '提示', {
    
    
      confirmButtonText: "确认"
    })
    removeFile()
  }).catch((err) => {
    
    
    console.log(err)
    ElMessage.info("简历投递已取消!")
  })
}

export function postFiles(url,data={
     
     }){
    
    
    return axios({
    
    
        method: "POST",
        url: 'http://127.0.0.1:8080'+url,
        transformRequest: [function(data, headers) {
    
    
            // 去除post请求默认的Content-Type
            delete headers['Content-Type']
            return data
        }],
        data: data,
    })
}

在这里插入图片描述
在这里插入图片描述


四. 后端接收代码

 @PostMapping("/uploadBatchTaxRevenue")
    public ResponseResult uploadBatchTaxRevenu(@RequestParam("file") MultipartFile[] files) throws IOException {
    
    
        if (files.length == 0) {
    
    
            return ResponseResult.okResult(403, "上传文件不能为空!");
        }
        for (MultipartFile file : files) {
    
    
            System.out.println(file.getName());
            EasyExcel.read(file.getInputStream(), TaxRevenue.class, new TaxRevenueDataListener(taxRevenueService))
                    .sheet()
                    .doRead();
        }
        return ResponseResult.okResult(200, "上传成功");
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_50913327/article/details/127230972