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 的状态

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)

}

});

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; // axios 的默认请求头

// 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 返回错误信息

}

)

// 添加返回拦截器

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

}

}

// 若服务器返回特定的通用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;

}

})

}, (err) => { // 如果有异常,则用于 promise 的 reject 回调

console.log(err.response)

if (err.response) {

error('服务器无响应,请联系系统管理员!') // 返回的异常error中,有 response 的,一般是 status为 505 500 501(服务器正在更新)

} else {

error('网络无连接,请检测网络设置!') // 没有response的,说明网络没有连接

}

});

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 。

})

})

};

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_...
我来评几句
登录后评论

已发表评论数()

相关站点

热门文章