axios请求响应拦截器

发布于:2024-08-08 ⋅ 阅读:(212) ⋅ 点赞:(0)

目录

axios-拦截器

拦截器的作用

 请求拦截器-基本写法:

axios请求拦截器-统一设置token

需求:

核心步骤:

关键代码:

响应拦截器-基本写法:

axios响应拦截器-统一处理token失效

需求:

核心步骤:

关键代码:

axios响应拦截器-数据剥离

需求:

核心步骤:

关键代码:


axios-拦截器

作用: 请求发送之前,响应回来之后执行一些 公共 的逻辑

不难发现, 这其实就是一个顺序链表能实现的,把请求拦截器的函数推在前面, api请求的核心方法放在中间, 响应拦截器放在数组后面,遍历执行链表就实现了拦截器的顺序执行过程。

拦截器的作用

a. 统计api从发起请求到返回数据需要的时间

b. 配置公共的请求头,加载弹窗等

c. 对响应状态码做拦截,比入后端返回400或500的状态码, 返回对应错误信息

  1. 注册之后,调用接口
  2. 请求发送时--》执行请求拦截器--》服务器
  3. 服务器响应内容--》执行响应拦截器--》接收数据

 请求拦截器-基本写法:

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么,比如: 统一设置token
  // 通过config可以获取请求的设置,比如headers可以获取(修改)请求头
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

axios请求拦截器-统一设置token

通过请求拦截器统一设置token

需求:

  1. 通过请求拦截器统一设置token
  2. 设置一次之后后续调用接口不用单独设置

核心步骤:

  1. 添加请求拦截器
  2. 统一设置token
  3. 移除首页对应逻辑

关键代码:

  1. commons.js
// 添加请求拦截器
// 统一携带token
axios.interceptors.request.use(function (config) {
  // 可以通过headers,查看+设置请求头
  // config.headers['info'] = 'itheima666'
  // 每次发送请求,都会执行这个回调函数
  // console.log(config)
  // 在发送请求之前做些什么,比如: 统一设置token
  const token = localStorage.getItem('token')
  // token存在,才携带
  if (token) {
    config.headers['Authorization'] = token
  }
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

  1. index.js
// 首页-统计数据
async function getData() {
  try {
    // 调用接口(登录成功之后才可以调用)
    const res = await axios({
      url: '/dashboard',
      // 通过axios请求拦截器统一携带
    })
    const overview = res.data.data.overview
​
    // 渲染数据
    Object.keys(overview).forEach(key => {
      document.querySelector(`.${key}`).innerText = overview[key]
    })
  } catch (error) {
    // 首页-登录状态过期
    // 判断token失效(状态码401):token过期,token被篡改
    // console.dir(error)
    if (error.response.status === 401) {
      // 删除缓存并提示用户
      localStorage.removeItem('username')
      localStorage.removeItem('token')
      // 使用普通用户可以理解的方式提示他们
      showToast('请重新登录')
​
      // 返回登录页
      setTimeout(() => {
        location.href = 'login.html'
      }, 1500)
    }
  }
}

响应拦截器-基本写法:

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么,比如: 数据剥离
  return response;
}, function (error) {
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么: 比如统一处理token失效
  return Promise.reject(error);
});

axios响应拦截器-统一处理token失效

axios响应拦截器-统一处理token失效

需求:

  1. 通过 axios响应拦截器-统一处理token失效

核心步骤:

  1. 添加响应拦截器
  2. 统一处理token失效
  3. 移除首页对应逻辑

关键代码:

  1. common.js
// 添加响应拦截器
// 统一处理token过期
axios.interceptors.response.use(function (response) {
  // 2xx 范围内的状态码都会触发该函数。
  return response;
}, function (error) {
  // console.dir(error)
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么: 比如统一处理token失效
  // 统一处理token失效
  if (error.response.status === 401) {
    // 弹框提示用户
    showToast('请重新登录')
    // 删除缓存
    localStorage.removeItem('token')
    localStorage.removeItem('username')
    // 返回登录页
    setTimeout(() => {
      location.href = 'login.html'
    }, 1500)
  }
  return Promise.reject(error);
});
  1. index.js
// 首页-统计数据
async function getData() {
  // 调用接口(登录成功之后才可以调用)
  const res = await axios({
    url: '/dashboard',
    // 通过axios请求拦截器统一携带
  })
  const overview = res.data.data.overview
​
  // 渲染数据
  Object.keys(overview).forEach(key => {
    document.querySelector(`.${key}`).innerText = overview[key]
  }) 
}

axios响应拦截器-数据剥离

axios响应拦截器-数据剥离

需求:

  1. axios响应拦截器-数据剥离
  2. 页面中使用数据时少写一个data

核心步骤:

  1. 剥离data属性(响应拦截器)
  2. 调整数据使用逻辑(登录,注册,首页)

关键代码:

  1. commons.js
// 添加响应拦截器
// 统一处理token过期
// 数据剥离
axios.interceptors.response.use(function (response) {
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么,比如: 数据剥离
  // 剥离data属性,页面中少写.data属性,直接可以获取到数据
  return response.data;
}, function (error) {
  // console.dir(error)
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么: 比如统一处理token失效
  // 统一处理token失效
  if (error.response.status === 401) {
    // 弹框提示用户
    showToast('请重新登录')
    // 删除缓存
    localStorage.removeItem('token')
    localStorage.removeItem('username')
    // 返回登录页
    setTimeout(() => {
      location.href = 'login.html'
    }, 1500)
  }
  return Promise.reject(error);
});

  1. index.js:移除多余的.data
// 首页-统计数据
async function getData() {
  // 调用接口(登录成功之后才可以调用)
  const res = await axios({
    url: '/dashboard',
    // 通过axios请求拦截器统一携带
  })
  const overview = res.data.overview
​
  // 渲染数据
  Object.keys(overview).forEach(key => {
    document.querySelector(`.${key}`).innerText = overview[key]
  }) 
}
  1. register.js:移除多余的.data,try中
document.querySelector('#btn-register').addEventListener('click', async () => {
  // 1. 收集并校验数据
  const form = document.querySelector('.register-form')
  const data = serialize(form, { empty: true, hash: true })
  // console.log(data)
  const { username, password } = data
  console.log(username, password)
  // 非空校验
  if (username === '' || password === '') {
    showToast('用户名和密码不能为空')
    return
  }
​
  // 长度校验
  if (username.length < 8 || username.length > 30 || password.length < 6 || password.length > 30) {
    showToast('用户名的长度为8-30,密码的长度为6-30')
    return
  }
​
  // 2. 数据提交
  try {
    // .post 请求方法 post,参数1:请求URL,参数2:提交的数据
    const res = await axios.post('/register', { username, password })
    // console.log(res)
    showToast(res.message)
  } catch (error) {
    // console.dir(error)
    showToast(error.response.data.message)
  }
})

  1. login.js:移除多余的.data,try中
document.querySelector('#btn-login').addEventListener('click', async () => {
  // 1. 收集并校验数据
  const form = document.querySelector('.login-form')
  const data = serialize(form, { empty: true, hash: true })
  console.log(data)
  const { username, password } = data
  // 非空判断
  if (username === '' || password === '') {
    showToast('用户名和密码不能为空')
    return
  }
​
  // 格式判断
  if (username.length < 8 || username.length > 30 || password.length < 6 || password.length > 30) {
    showToast('用户名长度8-30,密码长度6-30')
    return
  }
​
  // 2. 提交数据
  try {
    const res = await axios.post('/login', { username, password })
    // console.log(res)
    showToast(res.message)
    // 3. 缓存响应数据
    localStorage.setItem('token', res.data.token)
    localStorage.setItem('username', res.data.username)
    // 4. 跳转首页
    // 延迟一会在跳转,让提示框显示
    setTimeout(() => {
      // login.html和index.html的相对关系
      location.href = './index.html'
    }, 1500)
​
  } catch (error) {
    // console.dir(error)
    showToast(error.response.data.message)
  }
​
})


网站公告

今日签到

点亮在社区的每一天
去签到