Vue-axios-post資料後端接不到問題解決
1 前言
最近在前後端聯調的時候發現了一個問題,可能自己平時不注意傳送的內容格式,導致解決問題的路上,走了很多彎路,尤其是在剛剛懂了一點Vue知識之後,傳送請求的各種花式寫法也是讓人頭大,我在這把我踩到的坑給大家介紹一下吧。
2 問題
這個問題是我前端登入的時候向後端發生post請求。在使用這個介面前,我使用 postman 確認過了幾次,介面傳參是沒有問題的,而且使用params或者body傳參都是能接收到的。然而還是報錯了……我們先來看看一個截圖吧。
我向後端發引數的時候無論如何我都接不到資料,然後我就開始各種懷疑和猜測
( a )後端介面問題
如果是後端介面問題,那麼我用postman接到了呀,所以這一條雖然我不信,但是我還是去各種嘗試修改,我修改的介面傳遞方式,我懷疑是不是跨域失敗,然而都沒能解決我的問題。
( b )懷疑跨域未成功
我仔細檢查了是否存在全域性代理(各種代理工具)
是否存在nodejs本身問題
( c )傳送引數問題
我的請求程式碼如下:
axios.post('/api/home/login',{ params: { username: this.username,password: this.password } }).then(this.handleLoginSucc)
我自認為沒有問題,但是又不敢確定,於是我又換了一種寫法
// main.js配置 import axios from 'axios' // 配置請求的根路徑 axios.defaults.baseURL = 'http://localhost:8088/caeser/' Vue.prototype.$http = axios // 程式碼呼叫 // 設定同步方法 async const{ data: res } await this.$http.post('users',{ params: this.queryInfo })
然而並不能解決我的問題,因為傳送的內格式依然沒有變化。
最後我找了解決辦法,而且確定了內容格式是formdata
3 解決辦法
3.1 辦法1
var params = new URLSearchParams() // 引數儲存 params.append('username',this.loginForm.username) params.append('password',this.loginForm.password) // post傳送 axios.post('/api/home/login',params).then(this.handleLoginSucc)
這次我就能接到了,我們看看內容格式是什麼
Content-type依然是application/json,但是資料格式變成了 Form Data,於是問題迎刃而解了。
這個問題困擾了我兩天,算是吸取一個教訓吧,複習了一下請求方面的知識,算是有所進步了。
3.1.1 相容性
有個很重要提醒:所有瀏覽器都不支援URLSearchParams,但是有一個polyfill可用(確保polyfill全域性環境)
// 安裝 // npm install url-search-params-polyfill --save
ES2015+
import 'url-search-params-polyfill';
3.2 辦法2
這個辦法我建議使用,因為可以解決相容性問題
使用qs庫對資料進行編碼
var qs = require('qs'); axios.post('/foo',qs.stringify({ 'bar': 123 });
使用qs庫編碼傳送請求後端也是可以接收到的。
3.3 辦法3
不推薦使用
axios.post(url,{data:{},headers:{content-type:'application/x-www-form-unlencoded'} })
4 Request payload 和 FormData 區別
FormData和Payload是瀏覽器傳輸給後端介面的兩種內容格式,這兩種方式瀏覽器是通過Content-Type來進行區分的,如果是 application/x-www-form-urlencoded的話,則為formdata方式,如果是application/json或multipart/form-data的話,則為 request payload
下面內容為後端內容
4.1 後端程式碼如何處理這兩種格式
Request payload
對於 Request Payload 請求, 必須加 @RequestBody 才能將請求正文解析到對應的 bean 中,且只能通過 request.getReader() 來獲取請求正文內容
Form Data
無需任何註解,springmvc 會自動使用 MessageConverter 將請求引數解析到對應的 bean,且通過 request.getParameter(…) 能獲取請求引數
我自己後端程式碼就是因為沒有使用 request.getReader() 來獲取,才出現的問題
上面內容為後端內容
5 複習js和jquery的請求
jquery的請求很方便,格式很清晰
$.ajax({ url : targeturl,type : 'POST',data : formData,contentType : false,processData : false,cache : false,success : function(data) { if (data.success) { // success } else { // error } } });
JavaScript
function sendData(data) { var XHR = new XMLHttpRequest(); var urlEncodedData = ""; var urlEncodedDataPairs = []; var name; // 將資料物件轉換為URL編碼的鍵/值對陣列。 for(name in data) { urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name])); } urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g,'+'); // 定義成功資料提交時發生的情況 XHR.addEventListener('load',function(event) { // }); // 定義錯誤提示 XHR.addEventListener('error',function(event) { // }); // 建立我們的請求 XHR.open('POST','https://example.com/cors.php'); // 為表單資料POST請求新增所需的HTTP頭 XHR.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); // 最後,傳送我們的資料。 XHR.send(urlEncodedData); }
6 Axios知識點
6.1 全域性預設值
axios.defaults.baseURL = 'https://caeser.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
6.2 攔截器
//新增請求攔截器 axios.interceptors.request.use(function(config){ // before success // must return config // 必須返回config return config; },function(error){ // error }) //新增響應攔截器 axios.interceptors.response.use(function(response){ // return response; },function(error){ // error });
或者自定義實體
var instance = axios.create(); instance.interceptors.request.use(function () {/*...*/});
7 總結
在學習vue的過程中是非常容易的,因為vue真的很方便使用,學起來很快,都是模板語法,直接COPY就行了,而且邏輯性很簡單,就是在使用的時候,各種版本和外掛要學會除錯,多嘗試多使用,而且為了好好寫前端,我都下載了離線的CSS樣式檔案,因為很多樣式我都沒背下來,而且很多樣式我都不知道,有很多新的好用的特性,都是值得使用的。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。