zoukankan      html  css  js  c++  java
  • 【原创】浅谈ajax和axios的使用不同点和,以及SpringMvc接收参数的形式

    引言

    有很多人的误区就是使用axios或者ajax传递json参数时,后端必须要用某种手段处理,例如 很多人认为axios传递json必须用mvc的@RequestBody处理,因为axios默认的ContentType为 application/json ,这种‘必须’的表述是错误的,是对编程的误解,程序不是一成不变的。

    我们在入门时常用form表单进行数据提交操作,此时的请求头中使用的 content-type 是 application/x-www-form-urlencoded 也就是formData 表单格式数据,表单格式的数据传递特点就是key value形式的键值对,form表单会进行处理成 "name=xxx&age=xxx" 的形式。如下

    <form action="http://localhost:8080/user/login1.do" method="post">
       用户名<input type="text" v-model="formData.username" name="username"><br>
       密码<input type="password" v-model="formData.password" name="password" ><br>
       <input type="submit" value="提交">
    </form>

     

    后端使用springmvc取值,这也是最常规的取值方案了

    @RequestMapping("/login1")
    @ResponseBody
    public Result login1(String username,String password){
       System.out.println("login1>>>>>>>u:"+username+",p:"+password);
       return new Result(true,"登录成功");
    }

     Ajax

    我们在引言中清楚的知道了form表单的传参特性,下面来讲一下ajax,此时我们来试一下

     var vue = new Vue({
       .....
       data: {
       //  提交给后台的数据 都是在data中声明的
           formData: {
              username: '',
              password: ''
           },
      .....    
     let baseUrl = "http://localhost:8080/user/login1.do";
    // 发送 post 请求
    $.ajax({
         url: baseUrl,
         async: true,
         data: this.formData,
         success: function (res) {
             console.log(res)
          },
          type: "post",
          dataType: "json"
    })

    后端接收

    @RequestMapping("/login2")
    @ResponseBody
    public Result login2(LoginParam param) {
      System.out.println("login2>>>>>>>u:" + param.getUsername() + ",p:" + param.getPassword());
      return new Result(true, "登录成功");
    }

    从案例中我们发现 ajax 的默认的contentType 也是 application/x-www-form-urlencoded,并且和form标签做了相同的事情,那就是对一个json格式的数据进行了格式转换,也变成了form标签中的处理格式 "name=xxx&age=xxx" ,这里也是很多人的误区,很多人认为json只能用@RequestBody 搭配 application/json使用,却没有注意到ajax默认的ConentType也是formData,后端也是常规的接收方式不多赘述。 springmvc传参 https://www.cnblogs.com/xiaozhang666/p/13657846.html

    扩展  ajax对应@RequestBody的接收

    在使用是必须将contentType改为  application/json 并且 json转为json字符串,如下

    $.ajax({
        url: baseUrl,
        async: true,
        data: JSON.stringify(this.formData),
        contentType: "application/json",
        success: function (res) {
           console.log(res)
        },
        type: "post",
        dataType: "json"
    })

     后端接受

        @RequestMapping("/login3")
        @ResponseBody
        public Result login3(@RequestBody LoginParam param) {
            System.out.println("login3>>>>>>>u:" + param.getUsername() + ",p:" + param.getPassword());
            return new Result(true, "登录成功");
        }

    Axios

    使用过的人知道 axios的contentType默认为  application/json

    对于get方式的query传值并没有多大影响,只是data字段换为params

    let baseUrl = "http://localhost:8080/user/login1.do";
    // 发送 get 请求
    axios({
      method: 'get',
      url: baseUrl,
      params: this.formData
    }).then((res) => {
      console.log(res);
    })

    我们发现此时的 contentType在 axios 中的get请求并没有明确的指定,其实ajax的get时也没有明确指出。

    如图 params 给我们做的事就是把一个json格式的数据转换为 键值对并且把它拼接到url地址上,等效于

    "http://localhost:8080/user/login1.do?username=" + this.formData.username + "&password=" + this.formData.password

    重点

    一、axios   的 application/json 传递参数

    上面说过 axios的contentType默认为  application/json 那么我们试验一下post传递json格式

    let baseUrl = "http://localhost:8080/user/login3.do";
    // 发送 post 请求
    axios({
      method: 'post',
      url: baseUrl,
      data: this.formData
    }).then((res) => {
      console.log(res);
    })

     后端接收

    @RequestMapping("/login3")
    @ResponseBody
    public Result login3(@RequestBody LoginParam param) {
      System.out.println("login3>>>>>>>u:" + param.getUsername() + ",p:" + param.getPassword());
      return new Result(true, "登录成功");
    }

    我们此时发现这种axios写法完全等效于ajax的以下写法。。

    $.ajax({
        url: baseUrl,
        async: true,
        data: JSON.stringify(this.formData),
        contentType: "application/json",
        success: function (res) {
           console.log(res)
        },
        type: "post",
        dataType: "json"
    })

    就连后端接收参数都相同,那此时很明显 axios替我们做了ajax中的 JSON.stringify(this.formData) 的功能,就是将json 转换成为json字符串。

    二、axios   的 application/x-www-form-urlencoded  传递参数 也就是 表单formData

    上面的ajax默认为表单传递参数,直接传json时ajax把json转为键值对模仿了表单传递。那么我们有一个大胆的假设,将axios的contentType设置为 application/x-www-form-urlencoded ,这样我们是不是也可以用标准的json格式和常规的springmvc获取参数的形式获取到参数呢,而不再使用  application/json 搭配 @RequestBody了。

    直接开搞,将请求头 Content-Type 重新设置

    let baseUrl = "http://localhost:8080/user/login1.do";
    // 发送 post 请求
    axios({
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      method: 'post',
      url: baseUrl,
      data: this.formData
    }).then((res) => {
      console.log(res);
    })

    java常规接收

    @RequestMapping("/login2")
    @ResponseBody
    public Result login2(LoginParam param) {
       System.out.println("login2>>>>>>>u:" + param.getUsername() + ",p:" + param.getPassword());
       return new Result(true, "登录成功");
    }

    第一次结果

    我们发现ContentType的值修改了,但是formData的格式却成了一个json字符串格式,并不是from表单标准的键值对 "name=xxx&age=xxx" 格式,所以常规的参数绑定无法接收到参数,这里查了一下资料,这里需要手动的转换一下,将json转换为键值对,用axios文档提供的第三方 Qs.stringify() 方法转换。

    https://github.com/ljharb/qs  下的 dist  的 qs.js 进行引入到你的项目中。

    let baseUrl = "http://localhost:8080/user/login1.do";
    // 发送 post 请求
    axios({
       headers: {'Content-Type': 'application/x-www-form-urlencoded'},
       method: 'post',
       url: baseUrl,
       data: Qs.stringify(this.formData)
    }).then((res) => {
       console.log(res);
    })

    这样我们再试一下

     此时发现不同了,那就是原本的json串被转换成了键值对的形式,那么现在已经符合了form表单的发送数据的格式,我们再看看后端

     已经取到了。

    最后总结几点

    1. axios替我们做了json 转 json串的工作,JSON.stringify(this.formData)。
    2. ajax替我们做了 json转键值对的工作  ,Qs.stringify(this.formData)。
    3. 两种异步请求方法都没有硬性的要求,只不过是ContentType的转变。
    4. application/x-www-form-urlencoded 属性要传键值对,application/json 属性传值为 json字符串

     补充一种请求

    axios.post("http://localhost:8080/user/login1.do", "username=" + this.formData.username + "&password=" + this.formData.password, {
        headers: {'content-type': 'application/x-www-form-urlencoded'},
    }).then((response) => {
        //response.data就是服务器端返回的内容(例如json)
        console.log(response.data);
    }).catch((error) => {
        console.log(error);
        this.$message.error("网络异常");
    });

    此请求虽然是url拼接,但是不会出现在url中,因为是post

  • 相关阅读:
    pgspider sqlite mysql docker 镜像
    pgspider docker 镜像
    pgspider基于pg 的高性能数据可视化sql 集群引擎
    diesel rust orm 框架试用
    golang 条件编译
    Performance Profiling Zeebe
    bazel 学习一 简单java 项目运行
    一个好用node http keeplive agnet
    gox 简单灵活的golang 跨平台编译工具
    mailhog 作为smtp server mock工具
  • 原文地址:https://www.cnblogs.com/xiaozhang666/p/13693123.html
Copyright © 2011-2022 走看看