Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axios的拦截器原理及应用、简单手写核心逻辑? #128

Open
yanlele opened this issue Mar 19, 2023 · 0 comments
Open

axios的拦截器原理及应用、简单手写核心逻辑? #128

yanlele opened this issue Mar 19, 2023 · 0 comments
Labels
web框架 web 框架相关知识
Milestone

Comments

@yanlele
Copy link
Member

yanlele commented Mar 19, 2023

axios 拦截器的使用

Axios 是一个基于 Promise 的 HTTP 客户端库,可以用于浏览器和 Node.js 环境中发送 HTTP 请求。Axios 提供了拦截器机制,可以在请求发送前和响应返回后对请求和响应进行拦截和处理,从而实现一些通用的功能,例如:添加请求头、添加认证信息、显示 loading 状态、错误处理等。

Axios 的拦截器机制主要是通过 interceptors 属性来实现的,该属性包含了 requestresponse 两个对象,分别代表请求拦截器和响应拦截器。每个对象都包含 use 方法,该方法用于注册拦截器回调函数,拦截器回调函数会在请求发送前或响应返回后被调用。

下面是一个示例代码,展示了如何使用 Axios 的拦截器:

import axios from 'axios'

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  console.log('请求拦截器')
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  console.log('响应拦截器')
  return response
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error)
})

// 发送请求
axios.get('/api/user')
  .then(function (response) {
    // 处理响应数据
  })
  .catch(function (error) {
    // 处理请求错误
  })

在上面的代码中,我们首先通过 import 语句引入了 Axios 库。然后,我们调用 axios.interceptors.request.use 方法注册了一个请求拦截器回调函数,该函数会在发送请求前被调用,可以在该函数中进行一些通用的操作,例如添加请求头、添加认证信息等。接着,我们调用 axios.interceptors.response.use 方法注册了一个响应拦截器回调函数,该函数会在响应返回后被调用,可以在该函数中进行一些通用的操作,例如显示 loading 状态、错误处理等。

最后,我们使用 axios.get 方法发送请求,并通过 thencatch 方法处理响应数据和请求错误。在请求发送前和响应返回后,我们注册的拦截器回调函数会被自动调用,可以对请求和响应进行拦截和处理。

Axios 的拦截器机制非常强大,可以用于实现一些通用的功能,例如添加请求头、添加认证信息、显示 loading 状态、错误处理等。在实际开发中,我们经常会使用 Axios 的拦截器来提高代码的复用性和可维护性。

axios 拦截器原理

Axios 的拦截器机制是通过 interceptors 属性来实现的,该属性包含了 requestresponse 两个对象,分别代表请求拦截器和响应拦截器。每个对象都包含 use 方法,该方法用于注册拦截器回调函数,拦截器回调函数会在请求发送前或响应返回后被调用。

具体来说,当我们使用 axios 发送请求时,会先调用请求拦截器的回调函数,该函数会在请求发送前被调用,可以在该函数中进行一些通用的操作,例如添加请求头、添加认证信息等。如果请求拦截器返回的不是一个 Promise 对象,则会自动将其封装为一个 Promise 对象。

接着,Axios 会使用 XMLHTTPRequest 对象发送请求,并监听其状态变化事件。当响应返回后,Axios 会调用响应拦截器的回调函数,该函数会在响应返回后被调用,可以在该函数中进行一些通用的操作,例如显示 loading 状态、错误处理等。如果响应拦截器返回的不是一个 Promise 对象,则会自动将其封装为一个 Promise 对象。

需要注意的是,Axios 的拦截器是按照添加顺序依次执行的,也就是说,先添加的拦截器回调函数先执行,后添加的拦截器回调函数后执行。如果一个拦截器回调函数中没有调用 next 方法,则后面的拦截器回调函数将不会被执行。

下面是一个示例代码,展示了如何使用 Axios 的拦截器:

import axios from 'axios'

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  console.log('请求拦截器')
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  console.log('响应拦截器')
  return response
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error)
})

// 发送请求
axios.get('/api/user')
  .then(function (response) {
    // 处理响应数据
  })
  .catch(function (error) {
    // 处理请求错误
  })

在上面的代码中,我们首先通过 import 语句引入了 Axios 库。然后,我们调用 axios.interceptors.request.use 方法注册了一个请求拦截器回调函数,该函数会在发送请求前被调用,可以在该函数中进行一些通用的操作,例如添加请求头、添加认证信息等。接着,我们调用 axios.interceptors.response.use 方法注册了一个响应拦

axios 拦截器核心逻辑代码实现

下面是一个简单实现 Axios 拦截器核心逻辑的示例代码:

class Axios {
  constructor() {
    // 请求拦截器
    this.requestInterceptors = []
    // 响应拦截器
    this.responseInterceptors = []
  }

  // 注册请求拦截器
  useRequestInterceptor(callback) {
    this.requestInterceptors.push(callback)
  }

  // 注册响应拦截器
  useResponseInterceptor(callback) {
    this.responseInterceptors.push(callback)
  }

  // 发送请求
  async request(config) {
    // 执行请求拦截器
    for (const interceptor of this.requestInterceptors) {
      config = await interceptor(config)
    }

    // 发送请求
    const response = await fetch(config.url, {
      method: config.method,
      headers: config.headers,
      body: config.data
    })

    // 执行响应拦截器
    for (const interceptor of this.responseInterceptors) {
      response = await interceptor(response)
    }

    return response
  }
}

// 创建 Axios 实例
const axios = new Axios()

// 注册请求拦截器
axios.useRequestInterceptor(config => {
  // 在请求头中添加认证信息
  config.headers['Authorization'] = 'Bearer xxx'
  return config
})

// 注册响应拦截器
axios.useResponseInterceptor(response => {
  // 处理响应数据
  return response.json()
})

// 发送请求
axios.request({
  url: '/api/user',
  method: 'GET'
}).then(data => {
  // 处理响应数据
  console.log(data)
}).catch(error => {
  // 处理请求错误
  console.error(error)
})

在上面的代码中,我们首先定义了一个 Axios 类,该类包含了请求拦截器和响应拦截器两个属性,分别用于保存注册的拦截器回调函数。然后,我们定义了 useRequestInterceptoruseResponseInterceptor 两个方法,用于注册请求拦截器和响应拦截器回调函数。在这两个方法中,我们将回调函数保存到对应的属性中。

接着,我们定义了 request 方法,该方法用于发送请求。在 request 方法中,我们首先执行请求拦截器回调函数,将请求配置传递给回调函数,并将回调函数返回的结果赋值给请求配置。接着,我们使用 fetch 函数发送请求,并将响应保存到 response 变量中。然后,我们执行响应拦截器回调函数,将响应对象传递给回调函数,并将回调函数返回的结果赋值给响应对象。最后,我们返回响应对象。

在最后几行代码中,我们创建了一个 axios 实例,并使用 useRequestInterceptor 方法和 useResponseInterceptor 方法注册了请求拦截器和响应拦截器回调函数。然后,我们调用 request 方法发送请求,并使用 then 方法处理响应数据,使用 catch 方法处理请求错误。

@yanlele yanlele added the web框架 web 框架相关知识 label Mar 19, 2023
@yanlele yanlele added this to the milestone Mar 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
web框架 web 框架相关知识
Projects
None yet
Development

No branches or pull requests

1 participant