axios.js的封裝與使用

一 基於promise 封裝 axios
import axios from 'axios' // 工程中引入 axios 模塊,用於請求數據
import qs from 'qs' // 工程中引入 qs模塊,用於序列化表單,將請求參數轉成 form-data 格式
import { Message } from 'element-ui' // 統一採用 element-ui 的提示彈框
import store from 'src/store/store' // 引入Vuex,用於改變 state 的狀態html

const error = (prop) => { // 封裝 element-ui 的 message,用於錯誤提示
Message.closeAll();
Message({
message: prop,
type: 'error',
duration: 2000
})
}前端

let instance = axios.create({ // 實例化 axios
baseURL: '/mspapi', // 設置默認請求路徑,工程中全部 post 請求方法的請求路徑,都會在最前面默認添加 '/mspapi'
method: 'post', // 這樣封裝的優勢是,咱們不必在每個請求路徑前,都寫重複的代碼(前提是與 服務端 約定好)
headers: { // 請求頭
'X-Requested-With': 'XMLHttpRequest',
'x-auth-token': window.localStorage.getItem("_token_") // 以安控爲例,與服務端約定,登陸成功後的每一個請求都攜帶token (固然登陸接口/驗證碼接口沒有token)
}
});vue

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; // axios 的默認請求頭ios

// POST傳參序列化
instance.interceptors.request.use( // request-請求參數攔截器
(config) => {
config.data = qs.stringify(config.data, { arrayFormat: 'brackets' }); // 用於序列化表單,將請求參數轉成 form-data 格式
if (config.url.indexOf("/login/dologin") !== -1) { // 若是是登陸接口,就特殊判斷,請求頭不攜帶 token
config.headers = {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
};
} else { // 除了登陸路徑,其餘都須要攜帶 token
config.headers = {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'x-auth-token': window.localStorage.getItem("_token_")
};
}
return config; // 返回 封裝好 的請求參數
},
(error) => {
return Promise.reject(error) // es6語法 promise reject 返回錯誤信息
}
)es6

// 添加返回攔截器
instance.interceptors.response.use((rsp) => { // response-返回數據攔截器
return new Promise((resolve, reject) => { // 實例化一個 promise
// 處理登陸狀態
if (rsp.status === 203) { // 單獨處理狀態,前端將 203 轉化成 登陸超時
rsp.data.code = 101008
} else {
if (rsp.headers["x-auth-token"] && rsp.headers["x-auth-token"] !== "") { // 只有登陸接口的 response 返回參數會有 x-auth-token ,前端截取到該 token 存入瀏覽器本地存儲
window.localStorage.setItem("_token_", rsp.headers["x-auth-token"]) // 用於以後的請求參數 攜帶該 token
}
}element-ui

// 若服務器返回特定的通用code(大於100100),則特殊處理;
// 若返回其餘錯誤code,都返回後處理
switch (rsp.data.code) {
case 101005:
case 101008:
window.localStorage.clear(); // 清空本地存儲
store.commit("change_timeout", true); // Vuex全局登陸超時彈框
break;
case 101006:
window.localStorage.clear(); // 清空本地存儲
store.commit("update_license", true); // Vuex全局 license 已更新彈框
break;
case 101002:
case 101001:
window.localStorage.clear(); // 清空本地存儲
window.location.href = '/static/505.html'; // 登陸的用戶,沒有查看該頁面(或者調取該接口)的權限
break;
default:
resolve(rsp.data) // 其餘的 code 值都返回到具體的實例中 處理 (處理相應的業務邏輯)
break;
}
})axios

}, (err) => { // 若是有異常,則用於 promise 的 reject 回調
console.log(err.response)
if (err.response) {
error('服務器無響應,請聯繫系統管理員!') // 返回的異常error中,有 response 的,通常是 status爲 505 500 501(服務器正在更新)
} else {
error('網絡無鏈接,請檢測網絡設置!') // 沒有response的,說明網絡沒有鏈接
}
});api

const Post = (url, data) => { // 結合 es6 promise 封裝一個Vue全局的 Post 請求方法(該方法的請求路徑 會默認添加 '/mspapi')
return new Promise((resolve, reject) => {
data = data ? data : {}; // 處理請求參數,在這裏能夠 統一處理請求參數
let currentUrl = ''; // 因爲工程中不是全部的請求路徑都是以 '/mspapi' 開頭的
let box = ['/api/login/dologin', '/api/logout', '/api/check_current_user_pwd']; // 因此須要添加一個白名單,用於特殊處理
if (box.indexOf(url) > -1) {
currentUrl = url;
} else {
currentUrl = url;
}
instance.post(currentUrl, data) // 調用咱們上面封裝好的 axios 實例
.then(rsp => {
resolve(rsp); // resolve 服務端的返回值 response
})
.catch((error) => {
reject(error) // reject 錯誤信息,使用方法同 Post 。
})
})
};promise

const Get = (url, data) => { // 封裝一個全局的 Get 方法
return new Promise((resolve, reject) => {
instance.get(url, data)
.then(rsp => {
resolve(rsp.data);
})
.catch((error) => {
reject(error)
})
})
}瀏覽器

export { Post, Get, axios };

二 在 main.js 中 全局配置 axios

import { Post } from 'src/tools/axios.js'
Vue.prototype.$post = Post; // 賦值給 Vue 實例原型鏈,這樣全部的 *.vue 文件均可以直接使用 this.$post 調取數據了
注意:若是有 其餘方法或屬性 也想在Vue全局使用,均可以使用 Vue.prototype 來綁定在 Vue實例上,

不過,通常不推薦這麼使用,由於掛載太多的方法會影響性能。
       

    三 在具體的某一個 *.vue 文件中,使用封裝好的Post

this.$post("/updateUser/list") // "/mspapi/updateUser/list" 爲真正的請求路徑
.then(rsp => {
if (rsp.code == 0) {
this.updateList = rsp.data; // 與服務端的約定, code 爲 0 時,前端處理具體的頁面數據邏輯
} else {
this.$message({
message: rsp.msg, // code 不爲 0 且 code 值 不大於 100100 時,前端錯誤彈框提示 服務端返回的錯誤信息
type: "error"
});
}
})
.catch(err => {
console.log(err);
});

四 在Vuex 中使用封裝好的Post

import { Post } from "src/tools/axios";
import { Message } from 'element-ui';
import router from 'router/index'

const state = {
checkDataList: []
}

const getters = {
}

const actions = {
getCheckDataList({ dispatch, commit }, params) {
Post('/report/checkDataList', params) // 使用方法同上
.then(res => {
if (res.code == 0) {
commit("updateCheckDataList", res.data);
} else {
Message({
type: 'error',
message: res.msg
})
}
})
.catch(err => {
console.log(err)
})
}
}

const mutations = {
updateCheckDataList(state, prop) {
state.checkDataList = prop
}
}

export default {
namespaced: true,
state,
getters,
actions,
mutations
}
五 在 axios 中截獲 Cookies 並使用HTTP 傳遞給服務端
https://blog.csdn.net/weixin_...

相關文章
相關標籤/搜索