第一次写博客,前段时间遇到了一个文件上传的需求,没写过,花点时间研究了一下。故记录一下。

本文将举例一个简单的demo的前后端代码来说明,前端vue3+ts+axios,后端springboot。

前端代码:

<el-upload
  limit="1"   //上传文件数量限制
  :on-change="changeFile" //钩子,文件改变时触发
  :auto-upload="false" 
  :data="uploadForm.data">
   <template #trigger>
      <el-button size="small" type="primary">选取附件</el-button>
   </template>
   <el-button style="margin-left: 10px;" size="small" type="success" 
    @click="submitUpload">上传到服务器</el-button>
</el-upload>

相关API和属性可到element-plus官网查看:https://element-plus.org/zh-CN/component/upload.html#%E5%B1%9E%E6%80%A7

    const file = ref()
    const changeFile = (uploadFile) => {
     file.value = uploadFile;
 }
    const uploadForm = reactive({
    data: {
        fileId: '1',
        name: '2',
        type: '3'
    }
})
 const submitUpload = () => {
    const jsonStr = JSON.stringify(uploadForm.data);
    const blob = new Blob([jsonStr], {
        type: 'application/json'
    });
    let formData = new FormData();
    formData.append("obj", blob);
    formData.append("file", file.value.raw);
    let url = 'http://localhost:8080/upload' //访问后端接口的url
    let method = 'post'
    axios({
        method,
        url,
        data: formData,
    }).then(res => {
        debugger
        console.log(res);
        console.log(res.data);
    });
}

首先定义了一个ref类型的变量file,用来存储上传的文件。changeFile函数用于更新file的值。

接下来定义了一个reactive对象uploadForm,它包含一个名为data的属性,其中存储了fileId、name和type等信息。

submitUpload函数用于提交上传操作。首先将uploadForm.data对象转换为JSON字符串,并创建一个Blob对象。

然后创建一个FormData对象formData,将JSON字符串和file.value.raw(上传文件的原始内容)添加到formData中。

最后使用axios发送POST请求到指定的URL(这里是http://localhost:8080/upload),将formData作为请求数据发送。

可以看到我们这里向后端传的参数构成为文件+blob参数对象,用最原始的axios发送POST请求来请求后端数据。也没有设置headers请求头,因为浏览器会自动识别前端传的参数为什么格式?(我也不知道为啥,没有深究)。但有不少人说加了headers反而会报错。我这边加和没加都试了,没区别。

加请求头类型: 

 const submitUpload = () => {
    const headers 
     = {"Content-Type": "multipart/form-data"}// 设置HTTP请求头的Content-Type字段
    const jsonStr = JSON.stringify(uploadForm.data);
    const blob = new Blob([jsonStr], {
        type: 'application/json'
    });
    let formData = new FormData();
    formData.append("obj", blob);
    formData.append("file", file.value.raw);
    let url = 'http://localhost:8080/upload'
    let method = 'post'
    axios({
        method,
        url,
        data: formData,
        headers:headers
    }).then(res => {
        debugger
        console.log(res);
        console.log(res.data);
    });
}

 参数类型也为formData

后端代码:

@RestController
public class TestController {
    @PostMapping("/upload")
    ResponseEntity<?> upload(@RequestPart("file") MultipartFile file,
                             @RequestPart("obj") FileVo vo)throws  Exception{
        System.out.println(file);
        System.out.println(vo.getFileId());
        ObjectNode on = new ObjectMapper().createObjectNode();
        on.putPOJO("data","111");
        return  new ResponseEntity<>(on, HttpStatus.OK);
    }
}

 

@Data
public class FileVo {
    String fileId;
    String name;
    String type;
}

接收文件了类型参数用MultipartFile ,前端还有个blob的对象包含三个string类型的参数,就写个实体类FileVo 接收。

运行结果:

 

 后台接收到啦🎈🎈🎈🎈🎈

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐