【问题标题】:Axios middleware to use in all instances of axios在所有 axios 实例中使用的 axios 中间件
【发布时间】:2018-11-12 06:29:05
【问题描述】:

我在我的许多脚本中使用 import axios from 'axios 在我的反应应用程序中使用 axios。我想使用一种为所有 axios 调用/错误调用的中间件。我该如何处理?

【问题讨论】:

标签: reactjs axios middleware


【解决方案1】:

根据文档 - 您需要创建一个文件,即

// api-client.js

import axios from 'axios';

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    console.log(config);
    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);
  });

export default axios;

然后从您的容器或控制器中,导入上述文件:

// Home.js
import apiClient from './api-client.js';

【讨论】:

    【解决方案2】:

    拦截器是 Axios 执行此操作的方式。不过对我来说,它太有限了,纠结于 Axios 的 API,难以测试等等。

    Axios 中间件

    所以我编写了axios-middleware 模块,这是一个简单的中间件服务,它可以将自身挂接到您的 axios 实例(全局或本地)中,并提供一个简单、自包含且易于测试的中间件 API。

    注意:它在最小耦合非常重要的大型应用程序中大放异彩。

    简单示例

    这是simple example from the documentation

    import axios from 'axios';
    import { Service } from 'axios-middleware';
    
    const service = new Service(axios);
    
    service.register({
      onRequest(config) {
        console.log('onRequest');
        return config;
      },
      onSync(promise) {
        console.log('onSync');
        return promise;
      },
      onResponse(response) {
        console.log('onResponse');
        return response;
      }
    });
    
    console.log('Ready to fetch.');
    
    // Just use axios like you would normally.
    axios('https://jsonplaceholder.typicode.com/posts/1')
      .then(({ data }) => console.log('Received:', data));
    

    它应该输出:

    Ready to fetch.
    onRequest
    onSync
    onResponse
    Received: {userId: 1, id: 1, title: ...
    

    Testing a middleware

    假设我们有以下要测试的自包含中间件类。

    export default class ApiErrorMiddleware {
      constructor(toast) {
        this.toast = toast;
      }
    
      onResponseError(err = {}) {
        let errorKey = 'errors.default';
        const { response } = err;
    
        if (response && response.status) {
          errorKey = `errors.${response.status}`;
        } else if (err.message === 'Network Error') {
          errorKey = 'errors.network-error';
        }
    
        this.toast.error(errorKey);
        throw err;
      }
    }
    

    那真的很简单,我们甚至不需要mock Axios。

    import ApiErrorMiddleware from '@/middlewares/ApiErrorMiddleware';
    
    describe('ApiErrorMiddleware', () => {
      let toast;
      let middleware;
    
      // Jest needs a function when we're expecting an error to be thrown.
      function onResponseError(err) {
        return () => middleware.onResponseError(err);
      }
    
      beforeEach(() => {
        toast = { error: jest.fn() };
        middleware = new ApiErrorMiddleware(toast);
      });
    
      it('sends a code error message', () => {
        hasKey = true;
        expect(onResponseError({ response: { status: 404 } })).toThrow();
        expect(toast.error).toHaveBeenLastCalledWith('errors.404');
      });
    });
    

    【讨论】:

    • github.com/crazyfactory/tinka 前段时间我们有中间件需求,axois不支持,所以我们创建了tinka,现在虽然axios有,但是api真的很烂,所以我还是用tinka,国际海事组织要好得多。专门为您的 API 创建 SDK
    猜你喜欢
    • 2022-10-19
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 2021-07-01
    • 2020-03-25
    相关资源
    最近更新 更多