186-6908-0178
当前位置:首页 >程序开发
Vue 项目中 axios 的封装和API接口的管理
2018-04-12 202次浏览

10.webp.jpg

如图,面对一团糟代码的你~~~真的想说,What F~U~C~K!!!


回归正题,我们所要的说的axios的封装和api接口的统一管理,其实主要目的就是在帮助我们简化代码和利于后期的更新维护。


一、axios的封装

在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。如果还对axios不了解的,可以移步axios文档。


安装

npm install axios; // 安装axios复制代码


引入

一般我会在项目的src目录中,新建一个request文件夹,然后在里面新建一个http.js和一个api.js文件。http.js文件用来封装我们的axios,api.js用来统一管理我们的接口。


// 在http.js中引入axios

import axios from 'axios'; // 引入axios

import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到

// vant的toast提示框组件,大家可根据自己的ui组件更改。

import { Toast } from 'vant'; 

复制代码

环境的切换

我们的项目环境可能有开发环境、测试环境和生产环境。我们通过node的环境变量来匹配我们的默认的接口url前缀。axios.defaults.baseURL可以设置axios的默认请求地址就不多说了。


// 环境的切换

if (process.env.NODE_ENV == 'development') {    

    axios.defaults.baseURL = 'https://www.baidu.com';} 

else if (process.env.NODE_ENV == 'debug') {    

    axios.defaults.baseURL = 'https://www.ceshi.com';

else if (process.env.NODE_ENV == 'production') {    

    axios.defaults.baseURL = 'https://www.production.com';

}复制代码

设置请求超时

通过axios.defaults.timeout设置默认的请求超时时间。例如超过了10s,就会告知用户当前请求超时,请刷新等。


axios.defaults.timeout = 10000;复制代码

post请求头的设置

post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为application/x-www-form-urlencoded;charset=UTF-8


axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';复制代码

请求拦截

我们在发送请求前可以进行一个请求的拦截,为什么要拦截呢,我们拦截请求是用来做什么的呢?比如,有些请求是需要用户登录之后才能访问的,或者post请求的时候,我们需要序列化我们提交的数据。这时候,我们可以在请求被发送之前进行一个拦截,从而进行我们想要的操作。


请求拦截

// 先导入vuex,因为我们要使用到里面的状态对象

// vuex的路径根据自己的路径去写

import store from '@/store/index';


// 请求拦截器axios.interceptors.request.use(    

    config => {        

        // 每次发送请求之前判断vuex中是否存在token        

        // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况

        // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断 

        const token = store.state.token;        

        token && (config.headers.Authorization = token);        

        return config;    

    },    

    error => {        

        return Promise.error(error);    

})

复制代码

这里说一下token,一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token,如果token存在说明用户已经登陆过,则更新vuex中的token状态。然后,在每次请求接口的时候,都会在请求的header中携带token,后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。这时候或许有些小伙伴会有疑问了,就是每个请求都携带token,那么要是一个页面不需要用户登录就可以访问的怎么办呢?其实,你前端的请求可以携带token,但是后台可以选择不接收啊!


响应的拦截

// 响应拦截器

axios.interceptors.response.use(    

    response => {   

        // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据     

        // 否则的话抛出错误

        if (response.status === 200) {            

            return Promise.resolve(response);        

        } else {            

            return Promise.reject(response);        

        }    

    },    

    // 服务器状态码不是2开头的的情况

    // 这里可以跟你们的后台开发人员协商好统一的错误状态码    

    // 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等

    // 下面列举几个常见的操作,其他需求可自行扩展

    error => {            

        if (error.response.status) {            

            switch (error.response.status) {                

                // 401: 未登录

                // 未登录则跳转登录页面,并携带当前页面的路径

                // 在登录成功后返回当前页面,这一步需要在登录页操作。                

                case 401:                    

                    router.replace({                        

                        path: '/login',                        

                        query: { 

                            redirect: router.currentRoute.fullPath 

                        }

                    });

                    break;


                // 403 token过期

                // 登录过期对用户进行提示

                // 清除本地token和清空vuex中token对象

                // 跳转登录页面                

                case 403:

                     Toast({

            &nb

回到顶部