【原創】淺談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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM