【问题标题】:Axios: How to intercept and respond to axios requestaxios:如何拦截和响应axios请求
【发布时间】:2020-10-22 11:00:51
【问题描述】:

有没有办法在发送之前不仅拦截而且响应 axios 请求?如,从浏览器发送请求并从浏览器响应 + 阻止它发送请求。

我知道我可以使用axios interceptors 在请求和响应发送并返回到组件之前拦截它,并且我知道在请求拦截器中我可以抛出错误并用失败的请求触发响应拦截器。我怎样才能为成功的请求做同样的事情?给定某些条件,我希望 axios 响应,就好像它实际上从未通过拦截器时传递给服务器一样。这可能吗?

这是我目前所掌握的伪代码:

      axios.interceptors.request.use(
      request => {
        if (localResponse) {
              throw { isLocal: true, data: { hello: 'world' } }; // <- this will stop request and trigger 
                                                                 // response error. I want to trigger 
                                                                 // the actual response callback
        } else {
            return request;   // <- will perform full request
        }
      },
      error => {
        return Promise.reject(error);
      }
    );

    axios.interceptors.response.use(
      response => {
        return response; // <- I want to trigger this callback
      },
      error => { // <- so far i can only trigger a response error
        if (error?.isLocal) { 
          return Promise.resolve(error.data); 
        }
        
        return Promise.reject(error);
      }
    );

我已尝试仅解析请求拦截器,但它试图继续满足请求。有没有人有解决这个问题的创意?也许有比使用拦截器更好的解决方案?

【问题讨论】:

  • 您始终可以在生产代码中使用 mock Axios 库之一,例如 jest-mock-axios 或 moxios。只是一个想法¯\_(ツ)_/¯
  • 我认为这基本上是最后的选择。我在搞乱 Electron 并基本上通过 HTTP 和 IPC 使用 axios,剩下的唯一问题是停止 axios 请求,而是通过 IPC 发送数据并响应好像 axios 已经通过 HTTP 完成了请求。

标签: javascript axios


【解决方案1】:

设法自己编写了一个解决方案。这样我所有的 axios 调用都不必改变,我可以改变拦截器的行为。

注意:如果有人提出更好的解决方案,我会很乐意将他们的答案标记为正确并投赞成票。目前这是我能想到的最佳解决方案。

解决方案

这是我解决问题的方法

      axios.interceptors.request.use(
      request => {
        if (localResponse) {
              throw { isLocal: true, data: { hello: 'world' } }; // <- this will stop request and trigger 
                                                                 // response error. I want to trigger 
                                                                 // the actual response callback
        } else {
            return request;   // <- will perform full request
        }
      },
      error => {
        return error?.isLocal 
                    ? Promise.resolve(error); // <- triggers response intercept
                    : Promise.reject(error);
      }
    );

    axios.interceptors.response.use(
      response => {
        return response; 
      },
      error => {
          error?.isLocal 
                ? Promise.resolve(error); // <- sends as successful response
                : Promise.reject(error);
      }
    );

基本上我正在做的是抛出一个错误以阻止请求通过,然后解决错误而不是拒绝它。这有点hacky,但它完成了工作。

【讨论】:

  • 多么美丽的丑陋黑客:D
【解决方案2】:

你可以在本地场景中完全跳过请求吗?

function getData() {
  if (localResponse) {
    return Promise.resolve({ isLocal: true, data: { hello: 'world' }});
  }
  else {
    return axios.whatever;
  }
}
...
getData().then(...)

【讨论】:

  • 如果不发送我希望它跳过的请求,我无法让 Promise.resolve 工作
  • 在我上面的例子中,请求是在else块中发送的,所以它不可能发送和调用Promise.resolve
  • 你说得对,我想念它。这里的问题是,该解决方案需要我更改已经存在的结构并“包裹” axios,而不是利用已经存在的功能。通过使用拦截器,我可以添加此功能,而无需修改我所有的 axios 代码。对于我的特殊问题,我无法进行这种修改。不过,您的回答确实使我得到了自己的回答,这对我的头脑风暴很有帮助,所以谢谢;)
猜你喜欢
  • 2020-09-25
  • 2022-01-25
  • 2018-10-03
  • 2018-09-27
  • 1970-01-01
  • 2022-11-14
  • 2020-02-12
  • 2018-10-31
相关资源
最近更新 更多