Vue+axios使用FormData方式向后端发送数据


前言

在前后端分离的项目中经常使用到Vue+axios通过FormData的方式向后端(Java)发送表单数据(文字+图片),但是在初次写这个功能时,可能会遇到很多问题,本文详细的记录了该功能的实现。


一、该功能应用场景

前端向后端发送表单数据时,可能会同时发送图片和文本,这时会有一些需要注意的小细节。

二、代码示例

1.前端(使用的ant-design-vue,element-ui同理)

代码如下(示例):

<template>
  <a-form-model :model="form" :label-col="labelCol" :wrapper-col="wrapperCol">
    <a-form-model-item label="标题">
      <a-input v-model="form.title"/>
    </a-form-model-item>
    <a-form-model-item label="作者">
      <a-input v-model="form.author"/>
    </a-form-model-item>
    <a-form-model-item label="类型">
      <a-radio-group v-model="form.tag">
        <a-radio :style="radioStyle" :value="1">
          生活
        </a-radio>
        <a-radio :style="radioStyle" :value="2">
          学习
        </a-radio>
        <a-radio :style="radioStyle" :value="3">
          社会
        </a-radio>
      </a-radio-group>
    </a-form-model-item>
    <a-form-model-item label="图片资源">
    //此处开启了多选,并重写了brforeUpload方法,为了关闭自动提交和将图片转换为base64编码,同时声明了文件列表的类型
      <a-upload
          :multiple="true"
          :before-upload="beforeUpload"
          name="file"
          list-type="picture"
      >
        <a-button>
          <a-icon type="upload"/>
          上传推文图片
        </a-button>
      </a-upload>
    </a-form-model-item>
    <a-form-model-item label="正文">
      <a-input v-model="form.content" type="textarea"/>
    </a-form-model-item>
    <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
      <a-button type="primary" @click="onSubmit">
        提交
      </a-button>
    </a-form-model-item>
  </a-form-model>
</template>
<script>
import axios from "axios";

export default {
  data() {
    return {
      value: 1,
      radioStyle: {
        display: 'inline',
        height: '30px',
        lineHeight: '30px',
      },
      labelCol: {span: 4},
      wrapperCol: {span: 14},
      form: {
        title: '',
        author: '',
        tag: '',
        fileList: [],
        content: ''
      }
    };
  },
  methods: {
    beforeUpload(file, fileList) {
    //将图片转换为Base64编码
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        const base64 = reader.result;
        this.form.fileList.push(base64)
      };
      console.log(this.form.fileList)
       //禁止直接提交图片
      return false;
    },
    //提交表单
    onSubmit() {
      let formData = new FormData
      //此处需要和后端接收的参数名相同
      formData.append("form", JSON.stringify(this.form))
      axios.post(
      	  //后端接口,自行修改
          " http://localhost:8081/manage/submit",
          formData,
          {
            headers: {'Content-Type': 'multipart/form-data'}
          }
      ).then(res => {
        console.log(res.data.message)
      })
    },
  },
};
</script>

该段代码效果图:
在这里插入图片描述

2.后端

代码如下(示例):

@RestController
@Slf4j
@RequestMapping("/manage")
@CrossOrigin
public class ManageArticleController {
    @Resource
    ArticleService articleService;

    @PostMapping("/submit")
    public SystemResult<String> uploadImages(@RequestParam("form") String form)throws Exception {
    //这儿将传入的参数转换为对应的实体类
        ArticleVo articleVo=JSON.parseObject(form,ArticleVo.class);
        return SystemResult.success("上传成功");
    }
}

实体类:

@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
//对应的实体类
public class ArticleVo implements Serializable {
    private String title;
    private String author;
    private int tag;
    private List<String> fileList;
    private String content;
}

三、效果演示

前端向后端发送数据,后端打印显示
实现效果
在传入到后端后,可以自行根据需求将数据存入数据库

四、问题总结

1.前端发送的字段名和后端实体类的字段名不一致

将前端发送的数据名称和后端修改一致

2.跨域问题

后端接口上添加注解@CrossOrigin

3.文件上传的限制问题

在后端做相应的文件上传配置,比如上传大小,或者前端也做相应的验证。

4.不了解upload组件相关接口,导致功能无法实现

前往官网查看对应组件的api,实在看不懂的话可以按照我的配置来写。

  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 前端通过formdata方式文件,可以使用表单文件控件或者通过js代码创建formdata对象进行上。对于表单控件上,需要在form标签中设置enctype属性为multipart/form-data,然后在input标签中设置type属性为file,这样即可将文件存储在formdata对象中。如果通过js代码创建formdata对象,直接通过append方法将文件添加到对象中,如下所示: ``` let formData = new FormData(); formData.append('file', file); ``` 其中,file为需要上文件对象。 后端使用koa-body中间件可以方便地处理上文件。先要在koa应用中使用该中间件,然后通过ctx.request.files获取上文件,如下所示: ``` const Koa = require('koa'); const koaBody = require('koa-body'); const app = new Koa(); app.use(koaBody({ multipart: true, // 支持文件 formidable: { maxFileSize: 200*1024*1024, // 设置上文件大小,默认2M } })); app.use(async (ctx) => { const file = ctx.request.files.file; console.log(file.name, file.size); // 打印上文件名和大小 ctx.body = '上成功'; }) ``` 其中,multipart设置为true表示支持文件formidable对象中的maxFileSize表示最大上文件大小,默认为2M。在处理上文件时,获取文件对象通过ctx.request.files即可,可以获取文件名、类型、大小等信息。最后,需要设置返回的数据为上成功即可。 ### 回答2: 前端在实现文件的过程中,需要使用formdata对象,formdata对象可以支持上文件、文本信息以及表单数据等。要进行文件,需要注意选择文件类型的input的属性设置为"file",然后通过formdata对象将文件添加到数据中,在使用Ajax等技术将数据发送给后端。在使用formdata文件时,需要注意不同浏览器之间formdata对象的兼容性,可以使用polyfill等技术来进行统一。 对于后端的Koa框架来说,接收上文件可以使用koa-body中间件。koa-body中间件可以接收文件、文本信息以及表单数据等,可以将上文件保存在指定的路径下,并且将上文件信息添加到ctx.request.body中进行统一管理。在使用koa-body中间件时,需要注意对于文件大小、上路径、文件格式等进行配置管理,以免出现上失败或者数据丢失的情况。 除此之外,如何管理和处理上文件也是需要考虑的重点,可以考虑使用nodejs中的fs模块进行文件操作,或者使用第三方插件如multer等来进行统一管理。在处理上文件时,还要注意对于文件大小、路径、格式进行校验和处理,以确保数据的有效性和安全性。 ### 回答3: 前端使用Formdata来上文件,示例如下: ``` const formData = new FormData() formData.append('file', file) axios.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then((res) => { console.log(res.data) }) ``` 后端使用koa-body来接收上文件,示例如下: ``` const Koa = require('koa') const koaBody = require('koa-body') const app = new Koa() app.use(koaBody({ multipart: true, formidable: { uploadDir: './uploads', // 上文件保存的路径 keepExtensions: true, // 保留文件扩展名 maxFieldsSize: 2 * 1024 * 1024 // 最大文件大小为2MB } })) app.use(async (ctx) => { const file = ctx.request.files.file console.log(file) // 处理文件逻辑 }) app.listen(3000) ``` 其中,koa-body需要设置multipart为true,表示支持文件formidable则可以设置一些参数,如uploadDir表示文件保存的路径,keepExtensions表示是否保留文件扩展名,maxFieldsSize表示最大文件大小,可以根据需要进行调整。在处理请求时,可以通过ctx.request.files.file获取上文件信息,然后进行相应的业务逻辑处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑的像个child

好人一生平安,先磕为敬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值