問題來源: 在使用axios時,和java聯調,發現調接口服務器始終拿不到參數data,但是檢查network也的確傳了data,才有了該文章。
基於 vue-axios 和 $.ajax 兩種請求方式中數據傳輸的思考
以java為例,數據傳輸的起源:
一開始,Java為了實現前后端通信,在http協議允許下,制定了數據傳輸必須遵守的規則:
1) 數據傳輸 僅允許 以 字符串 或者 二進制流數據的方式傳輸, number object等格式 都不允許。
2) 規定了字符串數據傳輸的內容類型格式,即content-type,有以下幾種:
a) 底層的xmlhttprequest 默認的Content-Type 是 text/plain;charset=UTF-8
即: 數據可以為 “aaaa” , “[12313],{dsafdsafsd:12313}”
b) 原生的Form表單提交, 對 xmlhttprequest 的字符串數據加了規則校驗,
即 字符串數據 必須以key-value的方式存在,以便區分參數,於是鍵值對的概念出現了。
鍵值對以 & 隔開, 如: username=1111 & password=2222
為了和 以前的數據類型區分,則修改 Content-Type 為 application/x-www-form-urlencoded
並且以 input 的 name 為 鍵,value為值, 多個 input 以 & 隔開
<form>
<input name=“username” value=“1213”/>
<input name=“password” value=“321”/>
</form>
submit的時候,將 獲取所有 input 的鍵值對,形成 data: “username=1213&password=321”
發送到了后台,后台接受到該字符串,
c) 隨着互聯網發展,數據傳輸越來越復雜,form已經不足以滿足需求。
於是ajax出現了,並且 首先實現了 form 表單提交的功能
即 Content-Type 為 application/x-www-form-urlencoded,且數據傳輸為 鍵值對格式。
但是在 書寫方式上, data以 Object 的形式 書寫,內部實現將 Object 轉為 字符串鍵值對
又發展了一段時間, 出現了 一個新的 表述 key-value字符串數據的的方式,稱之為 JSON,
符合JSON格式的字符串 也讓服務器 很方便的獲取參數。
Ajax 又實現了該種傳參,
於是 ajax的 data:{username: 1213, password: 321} ,
最終傳輸時被 JSON.stringify(data) => “{“username”: 1213, “password”: 321}”
而服務器,則 JSON.parse(data),拿到了 data Object
為了區分該種數據格式,則修改 Content-Type 為 application/json
d) 又發展了一段時間,簡單的字符串傳輸也不滿足了,想傳輸文件,word,excel,txt,圖片等,即文件流傳輸
則由提出 一種數據內容格式,規定數據以 二進制 傳輸
並修改Content-Type 為 multipart/form-data
e)。。。。。
匯總content-type:
1)text/plain;charset=UTF-8
2)application/x-www-form-urlencoded 瀏覽器以 FormData 體現
3)application/json 瀏覽器以 requestPayload 體現
4) multipart/form-data
5)。。。。。。
以前的java服務器,為求代碼簡單,規定傳輸的字符串數據格式為 application/x-www-form-urlencoded,
所以 form 表單提交 和 $.ajax 都是默認 application/x-www-form-urlencoded
而后續 java出現各種框架, 如spring, 可以解決多種 傳參方式,如 application/json
后續的 第二代/三代 ajax,如 搭配vue的axios,都將默認的Content-Type修改為 application/json,
例子:
Vue項目倘若用了axios,而java的兄弟接收不到參數的話,則
1)必須修改 content-type類型為 application/x-www-form-urlencoded
2)還原鍵值對數據格式,通過qs模塊(不需要安裝,node自帶的)轉換數據格式即可
具體如下:(這里是在攔截器里進行設置,具體情況自己對照着處理)
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.interceptors.request.use(config => {
if(config.method === 'post'){
config.data = qs.stringify(config.data);
}
return config
}, error => {
// Do something with request error
Promise.reject(error)
})
其他的類ajax 也是一樣解決。