vue的axios使用時,Content-Type 引發的引數接收不到的問題回顧
問題來源: 在使用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) })