zoukankan      html  css  js  c++  java
  • vue框架搭建04-axios封装

    1、安装 axios  

    npm install axios --save

    2、在src目录里新建目录结构

    index.js内容

    // // axios封装
    // //1.引入axios
    import axios from 'axios'
    import { addPending, removePending } from "./cancleRequest.js"
    // // 2. 配置信息
    const config = {
    // 每次请求的协议、IP地址。 设置该配置后,每次请求路径都可以使用相对路径,例如"/admin/login"
    baseURL: "http://ztdoc.wisedu.com",
    // 请求超时时间
    timeout: 10000,
    // 每次请求携带cookie
    withCredentials: true,
    headers: {
    'Content-Type': 'application/json; charset=utf-8'
    }
    }
    // // 3.创建实例
    const instance = axios.create(config)

    // 1. 请求拦截
    instance.interceptors.request.use(
    // 请求之前做些什么
    config => {
    const url = [
    config.method,
    config.url,
    JSON.stringify(config.params),
    JSON.stringify(config.data)
    ].join('&')

    removePending(url) // 在请求开始前,对之前的请求做检查取消操作
    addPending(config) // 将当前请求添加到 pending 中
          const token = localStorage.getItem('token')
    if (token && config.url !== "auth/login/ids") {
    config.headers.Authorization = token
    }
    else {
    delete config.headers['Authorization']
    }
    return config
    },
    // 处理错误
    error => {
    return Promise.reject(error)
    }
    )

    // 2. 响应拦截
    instance.interceptors.response.use(
    // 对于成功响应的处理
    response => {
    const url = [
    response.config.method,
    response.config.url,
    response.config.params,
    response.config.data
    ].join('&')
          removePending(url) // 在请求结束后,移除本次请求
    switch (response.data.code)
    {
    case 500:
    console.error("后端网络错误")
    break;
    case 403:
    console.error('未授权,请重新登录')
    break;
    default:
    break;
    }
    return response.data
    },
    // 处理错误响应
    error => {
    // 判读异常是否是由取消请求导致的,
    if (axios.isCancel(error)) {
    console.error('repeated request: ' + error.message)
    } else {
    switch (error.response.status) {
    case 400:
    console.error('错误请求')
    break;
    case 401:
    console.error('未授权,请重新登录')
    break;
    case 403:
    console.error('拒绝访问')
    break;
    case 404:
    console.error('请求错误,未找到该资源')
    break;
    case 405:
    console.error('请求方法未允许')
    break;
    case 408:
    console.error('请求超时')
    break;
    case 500:
    console.error('服务器端出错')
    break;
    case 501:
    console.error('网络未实现')
    break;
    case 502:
    console.error('网络错误')
    break;
    case 503:
    console.error('服务不可用')
    break;
    case 504:
    console.error('网络超时')
    break;
    case 505:
    console.error('http版本不支持该请求')
    break;
    default:
    error.message = `连接错误${error.response.status}`
    }
    }
    return Promise.reject(error)
    }
    )
    // 二次封装
    const request = {
    get(url, param) {
    return new Promise((resolve, reject) => {
    instance({
    method: 'get',
    url,
    params: param
    }).then(res => {
    resolve(res)
    }).catch(err => {
    reject(err)
    // console.log(err, '异常')
    })
    })
    },
    post(url, param) {
    return new Promise((resolve, reject) => {
    instance({
    method: "post",
    url,
    data: param
    }).then(res => {
    resolve(res)
    }).catch(err => {
    reject(err)
    })
    })
    }
    }
    // 4. 导出
    export default request

      cancleRequest.js

    import axios from 'axios'
    // 声明一个 Map 用于存储每个请求的标识 和 取消函数
    const pending = new Map()
    /**
     * 添加请求
     * @param {Object} config
     */
    const addPending = (config) => {
        const url = [
            config.method,
            config.url,
            JSON.stringify(config.params),
            JSON.stringify(config.data)
        ].join('&')
        config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
            if (!pending.has(url)) { // 如果 pending 中不存在当前请求,则添加进去
                pending.set(url, cancel)
            }
        })
    }
    /**
     * 移除请求
     * @param {Object} config
     */
    const removePending = (url) => {
        if (pending.has(url)) { // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
            const cancel = pending.get(url)
            cancel(url)
            pending.delete(url)
        }
    }
    /**
     * 清空 pending 中的请求(在路由跳转时调用)
     */
    const clearPending = () => {
        for (const [url, cancel] of pending) {
            cancel(url)
        }
        pending.clear()
    }
    
    export { addPending, removePending, clearPending }
    

      在index.js的router.beforeEach

    下进行页面跳转时的拦截

    总结:

    缺点:axios内也只是封装了get 和post 类型没有完全写完。

    对 config  对象没有进行扩展,如果出现特殊http请求类型

    优点:对重复请求接口进行了拦截,

    页面跳转时取消了全部http请求

    第二次补充

    我一开始就是网上搜索然后自己做的。是按这种方式。

    但是后来测试的时候发现

    在 请求拦截里返回的是 config对象,请求参数也是一个对象。

    但是在响应拦截请求里 返回的response.config的data是一个字符串。

    所以用

    const url = [
    config.method,
    config.url,
    JSON.stringify(config.params),
    JSON.stringify(config.data)
    ].join('&')
    这种方法在removePending中回导致错误。
    比如请求参数是{a:'b'}在请求拦截中JSON.stringify变成“{a:'b'}”,
    但是在响应拦截中的data是已经是“{a:'b'}”了,再用JSON.stringify方法会变成”“{a:'b'}”“,导致用has()判断时不一样。
    永远无法从pendding消除.
    最后测试了一个请求发生时候的逻辑,

    添加之前先进移除方法。再进添加方法,

    请求完成再进移除方法。这才是对的

    
    
    
  • 相关阅读:
    牛客网 2018年东北农业大学春季校赛 L题 wyh的天鹅
    牛客网 2018年东北农业大学春季校赛 I题 wyh的物品
    记cccc天梯赛第三届决赛
    noi.openjudge 1.13.15
    Java连接Oracle数据库的三种连接方式
    SSH框架总结(框架分析+环境搭建+实例源码下载)
    深入浅出MyBatis:JDBC和MyBatis介绍
    每个 Java 开发者都应该知道的 5 个注解
    高效Web开发的10个jQuery代码片段
    编写优秀jQuery插件的10个技巧
  • 原文地址:https://www.cnblogs.com/cbb-web/p/14610849.html
Copyright © 2011-2022 走看看