axios的封装

为啥有现成的可以直接用 , 而要二次封装那么麻烦呢?

直接在vue文件中使用axios进行数据请求 , 会造成如下问题

1. 从项目分层的的角度看,业务层中又混入axios的API,缺少分层和模块化 , 不科学

2. 打包后 ,会将vue文件转换为html文件 ,所有请求都在html中,会有黑客将url进行反编译,进行攻击,获取资源,安全性低

3. 当一旦axios不在维护 , 不需要axios作为项目中请求的插件时,只需要改几个文件就行了, 不用满世界的改axios的API

目录结构

├─ src   
|  ├── api                                  
|  |   ├── api.js                          // 返回值和错误统一处理 ,  统一管理
|  |   ├── login.js                        //模块或页面下的请求
│  ├──request                               // 基本配置
│  │   ├── http.js                      //统一处理接口 , 拦截 , 状态处理
│  │   ├── url.js                        //接口url

http.js

import axios from 'axios';
import qs from 'qs';
import url from './url.js'
/**
 * 根据环境变量区分接口的默认地址
 */
switch (process.env.NODE_ENV) {
    case 'production':
        axios.defaults.baseURL = '生产环境下的公共请求url';
        break;
    case 'test':
        axios.defaults.baseURL = '测试环境下的公共请求url';
        break;
    default:
        axios.defaults.baseURL = url.BASEURL;
}

/**
 * 设置超时时间和跨域是否允许携带凭证
 */
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;

/**
 * 设置post请求头; 告知服务器请求主体的数据格式
 * x-www-form-urlencoded
 */
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.transformRequest = data => qs.stringify(data); //只对post有作用

/**
 * 设置请求拦截器
 * 客户端发送请求 - >[请求拦截器] - > 服务器
 * TOKEN校验(JWT):接收服务器返回的token , 存储到vuex/本地存储中,每次向服务器发请求,我们应该吧token带上
 */
// axios = axios.create({
//     baseURL: BASEURL, // 'https://mock.cangdu.org/mock/5fb233ffbcab7337c1b1c295/example', //请求接口公共部分
//     timeout: 5500 //等待时间
// })
axios.interceptors.request.use(
    config => {
        //假设服务端返回的token , 被存储在本地存储中
        //携带token
        let token = localStorage.getItem('token') || '';
        token && (config.headers.Authorization = token);
        return config;
    },
    err => {
        return Promise.reject(err);
    }
);

/**
 * 响应拦截器
 * 服务器返回信息 -> [拦截的统一处理] -> 客户端JS获取到信息
 */
// axios.defaults.validateStatus = status => {
//   //自定义响应成功的HTTP状态码
//   return /^(2|3)d{2}$/.test(status);
// }
axios.interceptors.response.use(response => {
    return response.data
}, error => {
    let {
        response
    } = error;
    if (response) {
        //起码服务器有返回结果
        switch (response.status) {
            case 401: //权限 当前请求需要用户验证(一般是未登录)
                break;
            case 403: //服务器已经理解请求 , 但拒绝执行它(一般TOKEN过期)
                localStorage.removeItem('token');
                break;
            case 404: //找不到地址
                break;
        }
    } else {
        //服务器没有返回结果
        if (!window.navigator.onLine) {
            //断网处理:可以跳转断网页面
            return;
        } else {
            return Promise.reject(error)
        }
    }

})

export default axios;

url.js

//接口url , 在编译时会打乱 , 反编译也无法获取 , 安全性提高
const BASEURL = 'https://mock.cangdu.org/mock/5fb233ffbcab7337c1b1c295/example';
const loginUrl = '/upload';
const getUrl = '/query'
export default {
    getUrl,
    loginUrl,
    BASEURL
}

api.js

import login from './login.js'
export default {
    login
}

login.js

import axios from "../request/http.js"
import url from '../request/url.js'

function loginOfPost(data) {
    return axios.post(url.loginUrl, data)
}

function loginOfGet(data) {
    return axios.get(url.getUrl, data)
}
export default {
    loginOfPost,
    loginOfGet
}

根据项目实际需求封装 , 本着业务层与API层分离的构思去封装 , 分模块进行处理 , 易于维护 , 且安全性更高

拓展思考

axios挂载在vue原型上,会污染原型,不建议这样做,但还没有找到更好的解决办法

//如果项目中用到了vuex , 可以尝试使用vuex这么玩
import axios from 'axios' const store = new Store() store.$axios = axios

最后

推荐几篇博客:

http://www.xiaoheidiannao.com/219695.html

https://blog.csdn.net/weixin_44287777/article/details/102974636

├─ src   |   ├── apis                                    |   |   ├── api.js                              // 返回值和错误统一处理 ,  统一管理|   |   ├── login.js                            //模块或页面下的请求│  ├──request                               // 基本配置│  │   ├── service.js                      //统一处理接口 , 拦截 , 状态处理│  │   ├── common.js                         //传参处理 │  │   ├── apiUrl.js                        //接口url

原文地址:https://www.cnblogs.com/wxyblog/p/14001238.html