代码之家  ›  专栏  ›  技术社区  ›  Akash Salunkhe

如何使用axios拦截器?

  •  1
  • Akash Salunkhe  · 技术社区  · 6 年前

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

    还有很多教程只显示这个代码,但我很困惑它是用来做什么的,有人能给我一个简单的例子来遵循。

    2 回复  |  直到 6 年前
        1
  •  143
  •   Aseem Upadhyay    6 年前

    简单来说,它更像是每个http操作的检查点。所做的每个api调用都通过这个拦截器传递。

    那么,为什么是两个拦截器?

    一些请求拦截器用例-

    假设您要在发出请求之前进行检查,您的凭据是否有效?因此,您可以在拦截器级别检查您的凭据是否有效,而不是实际进行api调用。

    假设您需要为每个请求附加一个令牌,而不是在每个axios调用中复制令牌添加逻辑,您可以创建一个拦截器,在每个请求上附加一个令牌。

    一些响应拦截器用例-

    假设您得到了一个响应,并根据api响应推断用户已登录。因此,在响应拦截器中,可以初始化处理用户登录状态的类,并在收到的响应对象上相应地更新它。

    假设您请求了一些具有有效api凭据的api,但您没有访问数据的有效角色。因此,您可以跳转一个来自响应拦截器的警报,说用户是不允许的。这样,您就可以避免未经授权的api错误处理,您必须对每个axios请求执行该错误处理。

    希望这有帮助:)

    编辑

    由于这个答案越来越受欢迎,下面是一些代码示例

    请求拦截器

    const DEBUG = process.env.NODE_ENV === "development";
    
    axios.interceptors.request.use((config) => {
        /** In dev, intercepts request and logs it into console for dev */
        if (DEBUG) { console.info("✉️ ", config); }
        return config;
    }, (error) => {
        if (DEBUG) { console.error("✉️ ", error); }
        return Promise.reject(error);
    });
    

    config.headers 对象。例如:

    axios.interceptors.request.use((config) => {
        config.headers.genericKey = "someGenericValue";
        return config;
    }, (error) => {
        return Promise.reject(error);
    });
    

    =>万一是个 GET 请求时,可以在中找到正在发送的查询参数 config.params 对象。

    =>你甚至可以 在拦截器级别解析api响应,并向下传递解析的响应,而不是原始响应。如果api在多个地方以相同的方式使用,那么它可以节省您一次又一次地编写解析逻辑的时间。一种方法是在 api-request 并在响应拦截器中使用相同的参数来执行操作。例如:

    //Assume we pass an extra parameter "parse: true" 
    axios.get("/city-list", { parse: true });
    

    一次,在响应拦截器中,我们可以像这样使用它:

    axios.interceptors.response.use((response) => {
        if (response.config.parse) {
            //perform the manipulation here and change the response object
        }
        return response;
    }, (error) => {
        return Promise.reject(error.message);
    });
    

    所以,在这种情况下,只要有 parse 中的对象 response.config ,操作完成,对于其他情况,它将按原样工作。

    =>你甚至可以看到 HTTP

    axios.interceptors.response.use((response) => {
        if(response.status === 401) {
             alert("You are not authorized");
        }
        return response;
    }, (error) => {
        if (error.response && error.response.data) {
            return Promise.reject(error.response.data);
        }
        return Promise.reject(error.message);
    });
    
        2
  •  17
  •   Constantin Chirila    6 年前

    它就像一个中间件,基本上是在任何请求(无论是GET、POST、PUT、DELETE)或任何响应(从服务器得到的响应)上添加的。 它通常用于涉及授权的情况。

    看看这个: Axios interceptors and asynchronous login

    下面是另一篇关于这一点的文章,有一个不同的例子: https://medium.com/@danielalvidrez/handling-error-responses-with-grace-b6fd3c5886f0

        3
  •  13
  •   Steve.g    4 年前

    例如,如果要捕获从发送请求到收到响应的时间,可以使用以下代码:

    const axios = require("axios");
    
    (async () => {
      axios.interceptors.request.use(
        function (req) {
          req.time = { startTime: new Date() };
          return req;
        },
        (err) => {
          return Promise.reject(err);
        }
      );
    
      axios.interceptors.response.use(
        function (res) {
          res.config.time.endTime = new Date();
          res.duration =
            res.config.time.endTime - res.config.time.startTime;
          return res;
        },
        (err) => {
          return Promise.reject(err);
        }
      );
    
      axios
        .get("http://localhost:3000")
        .then((res) => {
          console.log(res.duration)
        })
        .catch((err) => {
          console.log(err);
        });
    })();