Axios middleware to use in all instances of axios

最后都变了- 提交于 2019-12-10 14:23:17

问题


I'm using axios in my react app using import axios from 'axios in many of my scripts. I want to use sort of a middleware that is invoked for all axios calls/errors. How do I approach this?


回答1:


As the documentation- You need to create a file i.e

// axios.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;

//*** On other file import this-

// Home.js
import axios from './axios.js';



回答2:


Interceptors are the Axios way of doing this. For me though, it was too limited, tangled in Axios' API, difficult to test, etc.

Axios-middleware

So I wrote the axios-middleware module, a simple middleware service that hooks itself in your axios instance (either global or a local one) and provides a simple, self-contained and easily testable middleware API.

Note: it shines in bigger apps where minimal coupling is really important.

Simple example

Here's a 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));

It should output:

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

Testing a middleware

Say we have the following self-contained middleware class that we want to test.

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;
  }
}

Then it's really easy, we don't even need to 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');
  });
});


来源:https://stackoverflow.com/questions/53256914/axios-middleware-to-use-in-all-instances-of-axios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!