前端網路訪問,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,網路訪問較多的採用 vue-resources,Vue2.0 之後,官方不再建議使用 vue-resources ,這個專案本身也停止維護,目前建議使用的方案是 axios。今天鬆哥就帶大家來看看 axios 的使用。
axios 引入
axios 使用步驟很簡單,首先在前端專案中,引入 axios:
npm install axios -S
複製程式碼
裝好之後,按理說可以直接使用了,但是,一般在生產環境中,我們都需要對網路請求進行封裝。
因為網路請求可能會出錯,這些錯誤有的是程式碼錯誤導致的,也有的是業務錯誤,不管是哪一種錯誤,都需要開發者去處理,而我們不可能在每一次傳送請求時都去列舉各種錯誤情況。
因此我們需要對前端請求進行封裝,封裝完成後,將前端錯誤統一處理,這樣,開發者只需要在每一次傳送請求的地方處理請求成功的情況即可。
請求封裝
在 axios 中,我們可以使用 axios 自帶的攔截器來實現對錯誤的統一處理。
在 axios 中,有請求攔截器,也有響應攔截器。
請求攔截器中可以統一新增公共的請求引數,例如單點登入中前端統一新增 token 引數。
響應攔截器則可以實現對錯誤的統一處理。
另外一個需要注意的地方則是錯誤的展示需要使用一種通用的方式,而不可以和頁面繫結(例如,登入失敗,在使用者名稱/密碼輸入框後面展示錯誤資訊,不支援這種錯誤顯示方式),這裡推薦使用 ElementUI 中的 Massage 來展示錯誤資訊,這是一個頁面無關的元件。
封裝後的 axios 如下:
import axios from 'axios'
import {Message} from 'element-ui'
axios.interceptors.request.use(config => {
return config;
}, err => {
Message.error({message: '請求超時!'});
})
axios.interceptors.response.use(data => {
if (data.status && data.status == 200 && data.data.status == 500) {
Message.error({message: data.data.msg});
return;
}
if (data.data.msg) {
Message.success({message: data.data.msg});
}
return data.data;
}, err => {
if (err.response.status == 504 || err.response.status == 404) {
Message.error({message: '伺服器被吃了⊙﹏⊙∥'});
} else if (err.response.status == 403) {
Message.error({message: '許可權不足,請聯絡管理員!'});
} else if (err.response.status == 401) {
Message.error({message: err.response.data.msg});
} else {
if (err.response.data.msg) {
Message.error({message: err.response.data.msg});
}else{
Message.error({message: '未知錯誤!'});
}
}
})
複製程式碼
程式碼解釋:
- 首先匯入 axios 和 Massage 元件
- 接下來定義一個請求攔截器
- 最後定義一個響應攔截器,這個攔截器有兩個引數,第一個引數 data 表示服務端處理成功的響應,第二個 err 表示服務端處理失敗的響應。對照著 jQuery 中的 Ajax ,第一個相當於 success 回撥,第二個相當於 error 回撥。
- 響應的 data 表示服務端返回的資料,資料格式是
{data:{status:200,msg"",obj:{}},status:200}
其中,data 中的物件就是服務端返回的具體的 JSON ,外面的 status 表示 HTTP 響應碼,裡邊的 status 是自定義的 RespBean 中返回的資料 - 首先判斷 HTTP 響應碼為 200 ,並且服務端返回的 status 為 500 ,表示業務邏輯錯誤,此時直接通過 Message 將錯誤資訊展示出來,然後 return 即可。
- 如果服務端返回的欄位中包含 msg ,則將 msg 顯示出來,這個 msg 一般是成功的提示。
- 最後返回 data.data ,即將服務端返回的資料 return ,這個資料最終會來到請求呼叫的地方。
- 當 HTTP 響應碼大於等於 400 時,進入 err 中。
方法封裝
請求封裝完成後,還需要對方法進行封裝,方便呼叫:
let base = '';
export const postRequest = (url, params) => {
return axios({
method: 'post',
url: `${base}${url}`,
data: params,
headers: {
'Content-Type': 'application/json'
}
});
}
export const putRequest = (url, params) => {
return axios({
method: 'put',
url: `${base}${url}`,
data: params,
headers: {
'Content-Type': 'application/json'
}
});
}
export const deleteRequest = (url) => {
return axios({
method: 'delete',
url: `${base}${url}`
});
}
export const getRequest = (url) => {
return axios({
method: 'get',
url: `${base}${url}`
});
}
複製程式碼
由於在前後端分離專案中,大多數情況下,後端介面都採用 RESTful 風格來設計,所以前端主要封裝 GET\POST\PUT\DELETE
方法,然後所有的請求引數都是用 JSON。
這裡一開始定義了一個 base 變數,這是請求的字首,方便後期維護(如果需要統一修改請求字首)。
製作 Vue 外掛
封裝好的方法已經可以直接使用了,但是比較麻煩,每次使用時,都需要在相關的 vue 檔案中引入方法,像下面這樣:
import {postRequest} from "../utils/api";
複製程式碼
但是這種操作方式太麻煩,所以我們可以考慮將方法進一步封裝成 Vue 的外掛,這樣在每一個 vue 檔案中,不需要引入方法就能夠直接呼叫方法了。
參考 Vue 官方文件 cn.vuejs.org/v2/guide/pl…
官方給出了 5 種外掛製作方式,我們這裡採用第 4 種方案。 具體操作就是在 main.js 中引入所有的封裝好的方法,然後掛載到 Vue.prototype 上即可,如下:
import {postRequest} from "./utils/api";
import {putRequest} from "./utils/api";
import {deleteRequest} from "./utils/api";
import {getRequest} from "./utils/api";
Vue.prototype.getRequest = getRequest;
Vue.prototype.deleteRequest = deleteRequest;
Vue.prototype.putRequest = putRequest;
Vue.prototype.postRequest = postRequest;
複製程式碼
封裝完成後,以後在 vue 檔案中,直接通過 this 就可以獲取到網路請求方法的引用了,如下:
this.postRequest("/doLogin", this.user).then(msg=>{
if (msg) {
//登入成功,頁面跳轉
}
})
複製程式碼
注意 ,then 中的 msg 就是響應攔截器中返回的 msg ,這個 msg 如果沒有值,表示請求失敗(失敗已經在攔截器中進行處理了),如果有值,表示請求成功!
配置請求轉發
在前後端分離中,前端和後端在不同的埠或者地址上執行,如果前端直接向後端傳送請求,這個請求是跨域的。
但是在專案部署時,前端打包編譯後拷貝到 Java 專案中,和 Java 專案一起執行,此時不存在跨域問題。
所以這裡我們的解決思路不是解決跨域問題,而是通過配置 NodeJS 的請求轉發,來實現網路請求順利傳送。
請求轉發在 vue 專案的 config/index.js 檔案中配置:
新增了請求轉發配置之後,一定要重啟前端專案才會生效。
此時啟動前端專案,就可以順利傳送網路請求了。
總結
本文主要和大夥分享了在前後端分離的情況下,如何對前端網路請求進行封裝,並且如何配置請求轉發,這是前後端分離中的基礎課,小夥伴們有問題歡迎留言討論。鬆哥將自己封裝的網路請求庫已經放在 GitHub 上,歡迎大家參考 github.com/lenve/javab…。
關注公眾號【江南一點雨】,專注於 Spring Boot+微服務以及前後端分離等全棧技術,定期視訊教程分享,關注後回覆 Java ,領取鬆哥為你精心準備的 Java 乾貨!