【问题标题】:VueJS AXIOS - Is it correct to create an axios instance for every single request?VueJS AXIOS - 为每个请求创建一个 axios 实例是否正确?
【发布时间】:2021-11-16 03:34:17
【问题描述】:

我已经构建了一个 VueJS 应用程序,它使用 Vue-Axios 与 Laravel API 进行通信。

在我的项目中,我有一个 api.js 文件,其中包含以下代码:

import axios from "axios";

export function apiRequestProtocol(token = null) {
    var api_instance = axios.create({
        baseURL: "http://127.0.0.1:8000/api/",
    });

    if (token) {
        api_instance.interceptors.request.use(
            (config) => {
              config.headers.Authorization = `Bearer ${token}`;
              return config;
            },
            (error) => {
              return Promise.reject(error);
            }
        );
    } 
    return api_instance;
}

apiRequireProtocol 函数被导入到每个需要向 Laravel API 发出请求的 Vue 组件中。

如你所见,每次组件使用apiRequestProtocol(),都会创建一个新的Axios实例。

我这样做是因为来自 Axios 的一些“请求”需要access_token,而其他不需要。

我曾尝试对每个请求使用相同的 Axios 实例,只是更改其标头,但我无法成功。如果您知道如何根据请求仅使用一个实例来更改它(如果需要令牌或不需要),请告诉我如何。

此外,我想知道是否应该在使用这些实例后“删除”它们,或者是否有更好的方法来做到这一点。

谢谢!

我的 package.json:

{
  ...
  "dependencies": {
    "@vueuse/head": "^0.6.0",
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "vue": "^3.0.0",
    "vue-axios": "^3.2.5",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0",
    "vuex-persistedstate": "^4.1.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2"
  }
}

【问题讨论】:

  • "为每个请求创建一个 axios 实例是否正确?" - 不。 “我曾尝试对每个请求使用相同的 Axios 实例,只是更改其标头,但我无法成功地做到这一点”——考虑用你不成功的尝试重新提出这个问题。目前你有 XY 问题。

标签: javascript ajax api vue.js axios


【解决方案1】:

多个实例

不,您绝对不希望每个连接都有一个 axios 实例!但是您可能需要多个实例。具体来说,对于未经身份验证的请求,我会使用普通的axios.get,并为应用程序中的每个不同令牌使用一个实例。这样我就不必为添加和删除拦截器而烦恼了。

带有标头的普通 axios 请求

完全不用花哨的东西就可以完成:

axios.get(URL, {headers: {"X-my-custom-header": "my-custom-val"}})

不同标头的令牌认证

也可以这样:

var token_axios = axios.create({ BaseURL: "http://exam.pl" })
var token_interceptor = token_axios.intercepters.request.use(
  config => {
    config.headers.Authorization = "Token: MYTOKEN"
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
token_axios.get(url, {headers: {"x-my-custom-header": "abc"}})

覆盖令牌

可以完全按照我们最初设置的方式完成,并且

移除拦截器

如果我们先创建或获取它的引用就可以做到:

token_axios.interceptors.request.eject(token_interceptor)

(注意我们保存了上面的引用)。

虽然您可以每次都使用使用/弹出范例来修改一个实例,如果(我怀疑)令牌更改时令牌经常更改且请求很少,这将是正确的方法很少和请求很常见,我会简单地使用上面描述的几个对象。

回答您的另一个问题,虽然 JS 具有垃圾收集功能,但如果您创建了几十个一次性对象,手动删除它们是一种很好的做法,因为垃圾收集器在调用时会导致不可预知的减速。

参考

https://axios-http.com/docs/interceptors

【讨论】:

  • 谢谢,对我来说更清楚了
  • 好!我最近自己学习了 axios,所以我在很大程度上回答是为了让自己头脑清醒……这些东西在新的时候可能会令人困惑。如果它回答了问题,请随意接受。
猜你喜欢
  • 2019-04-20
  • 2023-01-26
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 2019-01-04
  • 2020-09-08
  • 2021-04-05
相关资源
最近更新 更多