十五、与服务端通信——axios(2)

本章概要

  • 创建实例
  • 配置默认值
  • 拦截器

15.6 创建实例

可以使用自定义配置调用 axios.create([config]) 方法创建一个 axios 实例,之后使用该实例向服务端发起请求,就不用每次请求时重复设置配置选项了。如下:

const instance = axios.create({
  baseURL:'https://some-domain.com/api/',
  timeout:1000,
  headers:{'X-Custom-Header':'foobar'}
})

15.7 配置默认值

对于每次请求相同的配置选项,可以通过为配置选项设置默认值来简化代码的编写。项目中使用的全局 axios 默认值可以在项目的入口文件 main.js 中按照以下形式进行设置。

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.withCredentials = true;

也可以在自定义实例中设置配置默认值,这些配置选项只有在使用该实例发起请求时才生效。如下:

// 创建实例时设置配置默认值
const instance = axios.create({
  baseURL:'https://api.example.com'
})

// 实例创建后更改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN

配置将按优先级顺序进行合并。顺序是先在 lib/defaults.js 中找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。如下:

// 使用由库提供的配置默认值来创建实例
// 此时超时配置的默认值是 0
var instance = axios.create();

// 覆写库的超时默认值
// 现在,在超时前,使用该实例发起的所有请求都会等待 2.5 s
instance.defaults.timeout = 2500;

// 在发起请求时,覆写超时值
instance.get('/login',{
  timeout:5000
})

15.8 拦截器

有时需要统一处理 HTTP 的请求和响应,如登录验证,这时就可以使用 axios 的拦截器,分为请求拦截器和响应拦截器,他们会在请求或响应被 then() 或 catch() 方法处理前拦截他们。axios 的拦截器的使用形式如下:

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

// 添加响应拦截器
axios.interceptors.response.use(function (res){
  // 对响应数据做些什么
  return res;
},function(err){
  // 对响应错误做些什么
  return Promise.reject(err);
})

《14.10.1 小节》 使用全局守卫实现了一个用户登录验证的例子,不过这种方式只是简单的前端路由控制,用户一旦成功登陆,前端就保存了用户登录的状态,允许用户访问受保护的资源。

如果在这期间,该用户在服务端失效了。例如,用户长时间未操作、服务端强制下线,或者管理员将该用户拉入黑名单,那么前端就应该及时更新用户状态,对用户的后续访问做出控制。

在这种情况下,就应该使用 axios 的拦截器结合 HTTP 状态码进行用户是否已登录的判断。如下:

// 请求拦截器
axios.interceptors.request.use(
  config => {
    if (token) {
      // 判断是否存在 token,如果存在,则每个 HTTP header 都加上 token
    }
    return config;
  },
  err => {
    return Promise.reject(err);
  }
)

// 响应拦截器
axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if(error.response){
      switch(error.response.status){
        case 401:
          // 如果返回 401 ,则清除 token 信息并跳转到登录页面
          router.replace({
            path:'login',
            query:{redirect:router.currentRoute.fullPath}
          })
      }
    }
    return Promise.reject(error.response.data);
  }
)

如果之后想移除拦截器,则可以按以下方式调用。

const myInterceptors = axios.interceptors.request.use(function(){
  // ...
})
axios.interceptors.request.reject(myInterceptors)

也可以为自定义的 axios 实例添加拦截器。如下:

const instance = axios.create();
instance.interceptors.request.use(function(){
  // ...
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小熊猫呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值