前言

这周在做一个小型的前后端分离的会议系统,前端使用的是Vue3,后端使用的是Springboot。原本以为前后端交互很简单,直接发送数据就可以了,没想到遇到了很多问题,具体说来就是:1、get和post请求应该如何向后端传递参数;2、前端请求体中参数的存储有哪几种格式,对于不同的存储方式后端应该如何去接收;3、http报文头的content-type到底有什么作用;4、字符集的编码应该如何指定;
接下来就让我们逐个来解决这些问题吧!

注意:axios所有请求中不用自己指定content-type了,也就是下面的代码中不需要传入headers对象了,人家好像会根据你传入的参数自动推断。

前端请求中参数的存储格式

前后端交互中肯定需要传递参数,在发送请求时我们需要在报文的头部headers指定content-type属性。参数有三种常见存储格式,接下来一一分析。

application/json

参数以json对象的格式发送,此时前端发送的对象可以直接是javascript语言的对象,后端需要使用@RequestBody注解接收参数,不能使用@RequestParam来接收。

优点

  • 前端发送数据简单,直接把参数对象传入即可

缺点

  • 后端必须有对应的参数类接收,当只传一个参数时不太方便。
postJson() {
    let config = {
        headers: {'Content-Type': "multipart/json, charset=UTF-8"}
    };
    let data = {
        fileName: '我爱你中国'
    };
    this.$axios
    .post('/api/file/testconttype', data, config);
}

multipart/form-data

form-data是浏览器中一种特殊的数据格式,当前端发送的数据为form-data格式时,参数的存储格式为参数名=参数值&参数名=参数值,可以通过RequestParam注解接收参数。

优点

  • 后端接收方便,可以单独接收某一个参数

缺点

  • 前端参数对象必须是FormData类型,属性需要逐个append进去
postFormdata() {
    let config = { 
        headers: {'Content-Type': "multipart/form-data, charset=UTF-8"}
    };
    // formdata对象
    let data = new FormData();

    data.append('fileName', '我爱你中国')

    this.$axios
    .post('/api/file/testconttype', data)
}

application/x-www-form-urlencoded

axios默认使用的是json格式,如果需要使用x-www-form-urlencoded格式,则需要使用QS库,想要了解的同学自己搜一下吧,个人觉得上面两种方式已经够用了,既可以传送单个参数,也可以传送整体的json对象

axios发送请求的两种方法

在vue3中我使用了axios模块进行请求,该模块提供了两种请求方式,即我们熟知的get请求和post请求。这里我们简单说一下两种请求方式的区别:get请求的参数会绑定到url后面,而post请求的参数会放入请求体中

使用axios发送get请求

因为get请求没有消息体,所有的参数都在Url中。所以使用axios发送get请求时如果需要传递参数就用params属性指定,值可以是一个js对象;后端接收时可以使用@RequestParam注解接收。

get() {
  let data = {
       fileName: '我爱你中国'
   };
   this.$axios
   .get('/api/file/testconttype', {
       params: data
   })
   .then(response => {
       alert(response.data.data);
   })
}

后端使用@RequestParam注解接收。

@RequestMapping("/testconttype")
public String test(@RequestParam String fileName) {
    logger.info(fileName);
    String s = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
    logger.info(s);
    return s;
}

使用axios发送post请求, 后端支持接收单个字段

想要让后端支持接收单个字段,前端就必须是FormData格式或x-www-form-urlencoded格式,所以参数对象就不能是简单的js对象了,具体代码如下:

postFormdata() {
    let config = { 
        headers: {'Content-Type': "multipart/form-data, charset=UTF-8"}
    };
    // formdata对象
    let data = new FormData();

    data.append('fileName', '我爱你中国')

    this.$axios
    .post('/api/file/testconttype', data)
}

后端使用@RequestParam注解接收。

@RequestMapping("/testconttype")
public String test(@RequestParam String fileName) {
    logger.info(fileName);
    String s = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
    logger.info(s);
    return s;
}

使用axios发送post请求, 后端整体接收json对象

前端可以发送简单的js对象给后端,后端使用@ResponseBody注解接收即可。

postJson() {
    let config = {
        headers: {'Content-Type': "multipart/json, charset=UTF-8"}
    };
    let data = {
        fileName: '我爱你中国'
    };
    this.$axios
    .post('/api/file/testconttype', data, config);
}

后端使用@RequestBody注解接收。

总结

  • 如果发送get请求,直接传入普通的js对象即可,axios会自动处理使得后端可以通过@RequestParam注解接收参数。
  • 如果使用post请求,后端想要接收单个参数,则需要传入FormData类型的参数,此时后端仍可以通过@RequestParam注解接收参数。
  • 如果使用post请求,后端想要整体接收参数,那么前端直接传入简单的js对象即可,后端使用@RequestBody注解接收。

参考文献

axios编码格式
@RequestBody注解的使用
Content-type详解,包括文件下载时应该使用的content-type
axios官网

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐