简体   繁体   English

在不同的文件/功能中捕获axios请求

[英]Catch axios requests in different files / functions

I use HTTP requests to get data for my Vue.js application. 我使用HTTP请求获取Vue.js应用程序的数据。 I have one file called Api.js with the base axios instance: 我有一个带有基本axios实例的名为Api.js的文件:

export default () => {
  return axios.create({
    baseURL: apiURL,
    headers: {
      Authorization: `JWT ${store.state.token}`
    }
  })
}

than I have a file called service.js , which contains the functions for the different endpoints: 比我有一个名为service.js的文件,其中包含不同端点的功能:

export default {
  status() {
    return Api().get('status/')
  }
}

In the .vue file I call the method like that. .vue文件中,我这样调用该方法。

created() {
  Service.status()
    .then(response => {
      // do something with the data
    })
    .catch(e => {
      // show exception
    })
}

Some exceptions should be handled in Api.js (for example: 401), some other exceptions should be handled in service.js and others in the .vue file. 某些异常应在Api.js中处理(例如:401),某些其他异常应在service.js中处理,其他应在.vue文件中处理。 How can I do that? 我怎样才能做到这一点?

Disclaimer: I have created two small axios plugins to achieve this specific pattern easily. 免责声明:我创建了两个小的axios插件来轻松实现此特定模式。

axios-middleware 爱可信的中间件

Simple axios HTTP middleware service to simplify hooking to HTTP requests made through Axios. 简单的axios HTTP中间件服务可简化对通过Axios发出的HTTP请求的挂钩。

It uses axios interceptors as mentioned by acdcjunior but it abstracts the use of axios with a commonly known middleware pattern so your app doesn't need to know and deal with the interceptor syntax. 它使用了acdcjunior 提到的 axios拦截器,但是它以一种众所周知的中间件模式抽象了axios的使用,因此您的应用无需了解和处理拦截器语法。

// import your API's axios instance
import http from './api';
import { Service } from 'axios-middleware';

// Create a new service instance
const service = new Service(http);

// We're good to go!
export default service;

You can then use this middleware service to register different middlewares anywhere in your app. 然后,您可以使用此中间件服务在应用程序中的任何位置注册不同的中间件。 A middleware can be as simple as an object or a reusable, easily testable class. 中间件可以像对象一样简单,也可以是可重用,易于测试的类。

import i18n from './services/i18n';
import toast from './services/toast';
import service from './services/middleware';
import { ApiErrorMiddleware, OtherMiddleware } from './middlewares';


// Then register your middleware instances.
service.register([
    // Middleware class instance
    new ApiErrorMiddleware(i18n, toast),
    new OtherMiddleware(),
    // or a simple object
    {
        onRequest() {
            // handle the request
        },
        onResponseError(error) {
            // handle the response error
        }
    }
]);

Where the ApiErrorMiddleware would be a simple class with the sole responsibility of showing toast messages on error. 其中ApiErrorMiddleware是一个简单的类,唯一的责任是在出错时显示Toast消息。

export default class ApiErrorMiddleware {
    /**
     * @param {VueI18n} i18n instance
     * @param {Object} toast message service
     */
    constructor(i18n, toast) {
        this.toast = toast;
        this.i18n = i18n;
    }

    /**
     * @param {Object} error
     */
    onResponseError(error = {}) {
        const { response } = error;
        let key = 'errors.default';

        if (response && this.i18n.te(`errors.${response.status}`)) {
            key = `errors.${response.status}`;
        } else if (error.message === 'Network Error') {
            key = 'errors.network-error';
        } else {
            // TODO log unhandled errors
        }
        this.toast.error(this.i18n.t(key));
    }
}

axios-resource 爱可信资源

Simple axios resource class to easily interact with a REST endpoint. 简单的axios资源类,可轻松与REST端点进行交互。

Define a resource class. 定义资源类。 Here, I added onError and onFetchError as examples for your use-case. 在这里,我添加了onErroronFetchError作为您的用例的示例。

import Resource from 'axios-resource';

export default class UserResource extends Resource {
    static URL = 'user/{id}';

    // This calls `sync` in the background
    fetch() {
        return super.fetch.apply(this, arguments)
            .catch(err => this.onFetchError(err));
    }

    onFetchError(err) {
        // An error occurred while fetching this resource.
    }

    onError(err) {
        // An error occurred with this resource
    }

    // called for every actions (fetch, create, patch, delete)
    sync() {
        return super.sync.apply(this, arguments)
            .catch((err) => this.onError(err))
    }
}

Then, in api.js , create an instance. 然后,在api.js ,创建一个实例。

import UserResource from './user';

const user = new UserResource();

// GET https://example.com/api/user/me
user.fetch('me')
    .then(({ data }) => {
        console.log('User data:', data);
    });

The error can be dealt with at every step. 该错误可以在每个步骤进行处理。

  1. in the onFetchError of this specific resource 在此特定资源的onFetchError
  2. in the onError of this resource 在此资源的onError
  3. in a middleware for the app. 在应用程序的中间件中。

You should add axios interceptors : 您应该添加axios拦截器

Axios Interceptors Axios拦截器

You can intercept requests or responses before they are handled by then or catch . 您可以在thencatch处理之前拦截请求或响应。

 // Add a request interceptor axios.interceptors.request.use(function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); }); // Add a response interceptor axios.interceptors.response.use(function (response) { // Do something with response data return response; }, function (error) { // Do something with response error return Promise.reject(error); }); 

Those can (should) be in your Api.js . 这些可以(应该)在您的Api.js中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM