javascript axios响应拦截器奇怪行为

watbbzwu  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(151)

这是我的fetch函数:

let fetch = async (data, method, url, responseType, header) => {
  axios.interceptors.response.use(
    function (response) {
      // Do something with response data
      return response;
    },
    function (error) {
      let errorObj;
      console.log(error);
      switch (true) {
        case error.response !== undefined:
          switch (error.response.status) {
            case 401:
              errorObj = {
                status: 401,
                message: error.response.data,
              };
              break;
            case 404:
              errorObj = {
                status: 404,
                message: error.message,
              };
              break;
            default:
              errorObj = {
                status: error.response.status,
                message: error.response.statusText,
              };
              break;
          }
          break;
        case error.request !== undefined:
          errorObj = error.request;
          break;
        default:
          errorObj = { message: error.message };
          break;
      }
      return Promise.reject(errorObj);
    }
  );
  let theRealURL = process.env["REACT_APP_SOCKET_URL"] + url;
  let requestObj = { method: method, url: theRealURL };
  if (method.toLowerCase() === "get") {
    requestObj.params = data;
  } else {
    requestObj.data = data;
  }
  if (responseType) {
    requestObj["responseType"] = responseType;
  }
  if (header) {
    requestObj["headers"] = header;
  }
  try {
    let response = await axios(requestObj);
    if (response.request.responseType === "blob") {
      let fileName = response.headers["content-disposition"];
      fileName = fileName.substring(fileName.indexOf("filename=") + 9);
      const newBlob = new Blob([response.data], {
        type: response.headers.get("content-type"),
      });
      const objUrl = window.URL.createObjectURL(newBlob);
      let link = document.createElement("a");
      link.href = objUrl;
      link.download = fileName;
      link.click();
    }
    return response.data;
  } catch (error) {
    throw error;
  }
};

我有一些API需要在调用它们之前进行身份验证。当会话超时时,我浏览一个通过链接调用这些API的页面,控制台中显示以下消息:

第175章:

第175章为什么要打电话
但是,当我按下“F5”按钮刷新网页时,它工作得很好。

prdp8dxp

prdp8dxp1#

每次调用fetch()时,似乎都在添加拦截器。拦截器只需要添加到Axios示例中一次,而不是重复添加。
这就是为什么您会看到相同内容的重复日志行。每一个拦截器的加入就像是一个链条中的一个环节。
从文档中

多拦截器

假设您添加了多个响应拦截器,并且何时满足响应

  • 然后执行每个拦截器
  • 则按添加顺序执行

更好的选择是配置Axios示例 * 一次 * 并使用该示例发出请求。
举个例子

// create and configure an instance
const api = axios.create({
  baseURL: process.env.REACT_APP_SOCKET_URL,
});

// add the response interceptor
api.interceptors.response.use(
  null, // default success handler
  (error) => {
    console.warn(error.toJSON());

    return Promise.reject({
      status: error.response?.status,
      message:
        error.response?.data ?? error.response?.statusText ?? error.message,
    });
  },
  {
    synchronous: true, // optimise interceptor handling
  }
);

const fetch = async (data, method, url, responseType, headers) => {
  const requestObj = {
    url,
    method,
    responseType,
    headers,
    [method.toLowerCase() === "get" ? "params" : "data"]: data,
  };

  const response = await api(requestObj); // use the created instance

  if (response.request.responseType === "blob") {
    let fileName = response.headers["content-disposition"];
    fileName = fileName.substring(fileName.indexOf("filename=") + 9);
    const newBlob = new Blob([response.data], {
      type: response.headers.get("content-type"),
    });
    const objUrl = window.URL.createObjectURL(newBlob);
    const link = document.createElement("a");
    link.href = objUrl;
    link.download = fileName;
    link.click();
  }
  return response.data;
};

相关问题