如何使用Vue.js定制Axios包和配置拦截器

88 阅读5分钟

使用Vue.js定制Axios包并配置拦截器

Axios是一个进行HTTP请求的库。它是一个围绕fetch API的封装器。它是一个基于承诺的API。

在大规模的应用中工作可能需要从服务器上发出大量的请求。Axios使得提出和管理这些请求变得容易。然而,可能需要处理对多个服务器的请求。

在本教程中,我们将学习如何向多个服务器发出请求。

先决条件

要跟上本教程,你需要具备以下条件。

  • 具有JavaScript或TypeScript的基本知识。
  • Vue.js的基本知识。
  • 一个支持TypeScript的集成开发环境(IDE)。
  • fetch API的理解。
  • 对Axios库的基本知识可能会有帮助,但这是不必要的。

目标

在本教程结束时,你将能够。

  • 向多个服务器发出请求。
  • 能够修改Axios库,了解它是如何工作的。
  • 添加一个拦截器来附加认证令牌。

什么是Axios库?

Axios库是一个围绕fetch API的封装器。

Axios使得在Node.js中进行和管理API请求变得容易。现在让我们继续,用Axios创建一个简单的应用程序,以更好地了解它是如何在更高层次上工作的。

首先,在你的项目根目录下安装Axios,如下图所示。

# initialise the package.json file
npm init
# install the Axios package
npm install axios

接下来,在你的index.ts 文件中添加以下脚本。

// initialise our axios
const axios= require("axios");
axios
    .get('https://api.github.com/users/section-engineering-education')
    .then((res)=>{
        console.log(res);
    })
.catch(err => {
    console.log(err)
})

在上面的代码中,我们正在请求GitHub的API。请求是向GitHub API发出的,而响应则是打印到控制台。

在本例中,我们请求GitHub API来获取用户的信息,名为section-engineering-education

输出。

  login: 'section-engineering-education',
    id: 78109665,
    node_id: 'MDEyOk9yZ2FuaXphdGlvbjc4MTA5NjY1',
    avatar_url: 'https://avatars.githubusercontent.com/u/78109665?v=4',
    gravatar_id: '',
    url: 'https://api.github.com/users/section-engineering-education',
    html_url: 'https://github.com/section-engineering-education',
    followers_url: 'https://api.github.com/users/section-engineering-education/followers',
    following_url: 'https://api.github.com/users/section-engineering-education/following{/other_user}',
    gists_url: 'https://api.github.com/users/section-engineering-education/gists{/gist_id}',
    starred_url: 'https://api.github.com/users/section-engineering-education/starred{/owner}{/repo}',
    subscriptions_url: 'https://api.github.com/users/section-engineering-education/subscriptions',
    organizations_url: 'https://api.github.com/users/section-engineering-education/orgs',
    repos_url: 'https://api.github.com/users/section-engineering-education/repos',
    events_url: 'https://api.github.com/users/section-engineering-education/events{/privacy}',
    received_events_url: 'https://api.github.com/users/section-engineering-education/received_events',
    type: 'Organization',
    site_admin: false,
    name: null,
    company: null,
    blog: '',
    location: null,
    email: null,
    hireable: null,
    bio: `“Section's Engineering Education (EngEd) Program is dedicated to offering a unique quality community experience for computer science university students."`,
    twitter_username: null,
    public_repos: 1,
    public_gists: 0,
    followers: 0,
    following: 0,
    created_at: '2021-01-27T20:10:11Z',
    updated_at: '2022-03-01T15:42:41Z'
  }

在上述响应中,你会注意到,我们可以使用Axios库从GitHub API中检索到关于这个网站(工程教育)的所有细节。

现在,当我们想向多个服务器(比方说SectionGitHub服务器)发出这个请求时会发生什么?

在下一节,我们将设置我们的Vue.js应用程序,它将使用Axios实例请求Section和GitHub服务器。

设置Vue.js应用程序

为了设置我们的Vue.js应用程序,我们将使用以下命令。

vue create axios-example-app

接下来,cd ,进入应用程序根目录,运行以下命令。

npm i axios

输出。

...
 "dependencies": {
    "axios": "^0.26.1",
    "core-js": "^3.6.5",
    "vue": "^2.6.11"
  },

本教程中使用的Axios版本可能与你的版本不同,这取决于你安装它的时间。

随着Vue应用程序的设置,我们现在将着手创建我们的Vue.js应用程序。

src ,创建一个名为services 的新目录。接下来,在services 目录中,创建一个名为http/client 的新目录并添加一个名为client.js 的文件。

修改客户端文件,如下图所示。

// we first import the axios library
import axios from 'axios'
// we get the base url from the environment variables
import {apiBaseUrl} from "@/environment";
// we also import the auth service from the modules.
import {AuthService} from "@/modules/auth";
/**
 * Axios basic configuration
 */
const config = {
  baseURL: apiBaseUrl
}

/**
 * Creating the instance of Axios
 * It is because in large-scale application, we may need
 * to consume APIs from more than a single server,
 */
const client = axios.create(config)

/**
 * Auth interceptors
 * @description Add auth tokens to every outgoing request.
 * @param {*} config
 */
const authInterceptor = config => {
  config.headers.Authorization = `Bearer ${AuthService.token}`
  config.headers.common.Accept = 'Application/json'
  config.headers['Access-Control-Allow-Origin'] = '*'
  return config
}

/**
 * Logger interceptors
 * @description Log app requests.
 * @param {*} config
 */
const loggerInterceptor = config =>
/** Add logging here */
  config

/** Adding the request interceptors */
client.interceptors.request.use(authInterceptor)
client.interceptors.request.use(loggerInterceptor)

/** Adding the response interceptors */
client.interceptors.response.use(
  response => Promise.resolve(response),
  error => {
    Event.$emit('error', 500, error.response.data.message)
    if (error.response.status === 401) AuthService.logout()
    const errorMessage = error.response.data.message
    error.response.data.message = errorMessage.length > 200
      ? JSON.parse(errorMessage.split('code :').pop()).error.message.split(':')[0]
      : errorMessage
    throw error
    // Promise.reject(error)
  }
)

export default client

在上面的代码中,我们正在设置API的基本URL。我们还设置了auth拦截器。现在,我们不能使用基本的Axios包来请求受保护服务器的资源。

为了进行这些请求,我们需要创建一个Axios包的实例,并将其命名为client 。有了这个新的实例,我们可以使用axios.config() 方法来修改这个包,以附加我们的令牌。

这可以通过添加之前创建的Axios实例的interceptor 属性来实现,client 。然后,config.headers.Authorization =Bearer ${AuthService.token}`被用来附加向服务器发出请求所需的令牌。

正如下一步所讨论的,我们也让Axios响应处理成功和失败的消息。然后我们导出客户端实例,以便在其他模块中使用。

现在让我们继续,创建我们的Auth服务,如下所示。

// in the src/services/auth/auth.js file
class AuthService {
  // our constructor
  constructor () {
    // create an object with auth details
    this.obj = {
      token: `${process.env.VUE_APP_NAME}_token`,
      user: `${process.env.VUE_APP_NAME}_user`,
    }
    // get the auth token from local storage
    this.token = window.localStorage.getItem(this.obj.token)
    // get the current user from local storage
    this.user = JSON.parse(window.localStorage.getItem(this.obj.user))
  }
  // check if user is authenticated
  check () {
    return !!this.token
  }
  // get the token
  token () {
    return !!this.token
  }
  // we getting the current user
  user () {
    return !!this.user
  }
  // logout the current user
  logout () {
    // unset the token and the user
    window.localStorage.removeItem(this.obj.token)
    window.localStorage.removeItem(this.obj.user)
    location.reload()
  }
  // login the user
  login ({ token, user }) {
    window.localStorage.setItem(this.obj.token, token)
    window.localStorage.setItem(this.obj.user, JSON.stringify(user))
    this.token = token
    this.user = user
    window.location = '/'
  }
  // set the value of the current user
  setUser (user) {
    window.localStorage.removeItem(this.obj.user)
    window.localStorage.setItem(this.obj.user, JSON.stringify(user))
    this.user = user
    location.reload()
  }
}
// export the auth service
export default new AuthService()

这个文件的创建,假设你的Vue应用程序有一个env ,否则在你的项目根部创建一个,并添加以下内容。

VUE_APP_NAME = Test
VUE_APP_API_BASE_URL=http://127.0.0.1:8080/api/v1/

在认证脚本中,我们创建了一个带有初始用户设置的构造函数。然后我们添加了一些公共方法,我们可以在导入这个认证服务时使用。

现在我们有了认证服务和Axios实例的定义,让我们在商店中设置一个动作,根据运行中的服务器请求多个服务器。

设置Vue商店

为了开始使用Vue的状态管理,我们需要安装一些软件包,包括Vuex。

vue add vuex

上面的命令会提示你yesno 问题,在这种情况下,你应该回答yes

输出。

 "dependencies": {
    ...
    "vuex": "^3.4.0" 
  },

必须注意的是,上述安装的版本可能因安装时间不同而不同。

接下来,让我们为我们的商店定义所需的设置,如下所示。

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {},
  mutations: {},
  getters: {},
  actions: {},
  modules: {}
});

Vuex是Vue.js的一个状态管理工具,就像我们为React提供的Redux和为Angular提供的NgRx一样。

它有5个关键组件,确保应用程序的状态以一种时尚的方式被维护。

由于我们要查询GitHub的API来获取用户,所以要更新商店,如下图所示。

import call from "@/service/http";
const BaseURL='https://api.github.com/users/';
export default {
    state: {
        githubUsers : [],
    },
    mutations: {
        MUTATE: (state, payload) => {
            state[payload.state] = payload.data;
        },
    },
    getters: {
        GithubGetter: state => (setup) => state[setup],
    },
    actions: {
        users: ({commit}, payload) => {
            call('get', BaseURL, payload)
                .then(response => {
                    commit("MUTATE", {
                        state: "githubUsers",
                        data: response.data.data,
                    });
                })
                .catch(error => {
                    Event.$emit("ApiError", error.response.data.message);
                });
        },
    }
}

在上面的存储文件中,我们定义了我们应用程序的状态,首先定义了一个GitHub用户数组作为我们的状态。然后我们创建了突变器,因为我们不想直接修改我们的状态。

接下来,我们定义了getter,以便从应用程序的任何地方访问我们的存储,以及一个向服务器发出请求的动作。

你可能已经注意到了,我们使用了call() 方法,而不是普通的axios 包来向远程服务器发出请求。(It's not a mistake).

发生的情况是,client 是我们之前创建的axios包的一个新实例。要使用这个客户端,在http/client 的根部添加一个文件,index.js ,并添加以下内容。

import client from './client/client'

export default async function call (requestType, url, data = null) {
  return client[requestType](url, data)
}

现在,上面的call(arg1,arg2,optional) 方法需要2个参数,有可选的有效载荷参数。当这个方法被调用时,它确保所有离开我们应用程序的请求都带有认证令牌和任何其他添加在头文件上的值。

这是修改axios的一种方法,可以根据你的要求进行自定义请求。有了这个新的实例,你可以只通过定义API基本URL来向服务器发出请求。

总结

在本教程中,我们已经看到了如何定制Axios包来创建一个拦截器。

然后我们配置了我们的商店,用这个新创建的实例向我们选择的服务器发出请求,call() ,这个方法需要3个参数。