1. Vue

  2. Node.js

  3. 构建工具

  4. 路由

  5. 接口请求

  6. 状态管理

拦截器使得我们可以在请求或响应之前执行相应的操作,可以查阅官方文档拦截器

最常见的场景,就是在请求之前加上登录信息,或者在响应之前针对特定的错误场景进行特定的处理,比如后端接口返回登录信息错误的情况下,统一跳转登录页面。

拦截器处理登录场景示例

拦截器有两个重要方法:

axios.interceptors.request.use: 绑定请求拦截器

axios.interceptors.response.use: 绑定响应拦截器

import axios from "axios"

import router from "../router"
import store from "../store"

export default {
    install: (app) => {
        // 创建 axios 实例
        const http = axios.create({
            // 设置 baseURL
            // baseURL 会被加在 url 前端,除非 url 是个绝对 URL
            baseURL: "https://3yya.com/u/d8cf630cf5f367cc/",
        })

        // 如何获取登录信息应视实际项目的处理逻辑确定
        // 示例项目是保存在了 Vuex 中
        // 获取 Vuex 中保存的 token
        const token = store.state.token

        // 添加请求拦截器,会在请求之前执行
        http.interceptors.request.use(
            function (config) {
                // 请求成功

                // 如果存在 token 表示有登录信息
                if (token) {
                    // 如何携带登录信息应视实际接口文档而定
                    // 三鸭的接口要求是在请求的 Authorization 中带上
                    config.headers["Authorization"] = token
                }
                return config
            },
            function (error) {
                // 请求出错
                return Promise.reject(error)
            }
        )

        // 添加响应拦截器,会在响应之前执行
        http.interceptors.response.use(
            function (response) {
                // 成功时执行
                // 2xx 的状态码
                return response
            },
            function (error) {
                // 失败时执行
                // 包括超时,网络错误,所有非 2xx 的状态码

                // 有 response 代表接收到了服务器的响应
                if (error.response) {
                    // 登录信息失效的响应各个后端接口各有不同,视实际接口文档而定
                    // 三眼鸭的接口登录无效的状态码为 400,错误 code 为 1100
                    if (error.response.status === 400) {
                        if (error.response.data.code === 1100) {
                            // 跳转到登录页面
                            // router 配置时已将登录页的 name 设置为 login
                            router.push({
                                name: "login",
                                // 在查询参数中携带当前页面的地址
                                // 待登录成功后返回
                                query: { before: document.location.href },
                            })
                        }
                    }
                }
                return Promise.reject(error)
            }
        )
        // 将创建的 axios 实例绑定到全局属性中
        app.config.globalProperties.$http = http
    },
}