我们可以使用 axios 拦截器来响应 window.fetch 发出的 http 调用吗?
Can we use axios interceptor for http calls made by window.fetch in react?
我们的 React 应用在其大部分或所有区域中使用 window.fetch 方法进行 http 调用。以前,它只有一个访问内容的令牌,而我们所做的是,我们在每个请求中单独添加一个 header,以发送令牌等。下面是此类请求的示例代码:
useEffect(() => {
// GET S3 CREDANTIONS
fetch("/dashboard/de/question/s3credentials", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${loginReducer}`,
},
})
但现在我们已经配置 api 访问两个令牌,一个用于访问内容,另一个用于刷新访问令牌。为此,在从互联网上搜索之后,我们决定添加一个 axios 拦截器,以在每次 http 调用之前检查 access_token 是否有效。
所以,我制作了拦截器并将其放在反应应用程序的 index.js 中。如果 access_token 有效,则在发送之前全局检查每个 http 请求;如果不是,请刷新。我从这个 link 得到了这个想法:
https://blog.bitsrc.io/setting-up-axios-interceptors-for-all-http-calls-in-an-application-71bc2c636e4e
除了这个link,我还从包括Whosebug在内的许多其他网站上学习了它,并且我对它的理解更多,所以应用了它。
下面是 index.js 文件中的 axios 拦截器的代码(整体):
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import axios from "axios";
import AdminIndex from "./AdminPanel/Pages/AdminIndex";
import Cookies from "js-cookie";
// React Redux
import allReducers from "./reducers/index";
import { createStore } from "redux";
import { Provider } from "react-redux";
import StateLoader from "./reducers/PresistedState";
const stateLoader = new StateLoader();
let store = createStore(
allReducers,
stateLoader.loadState(),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
axios.interceptors.request.use(
async (config) => {
let serverCallUrl = new URL(config.url);
if (serverCallUrl.pathname.includes("/superuser/login")) return config;
let access_token = Cookies.get("access");
let refresh_token = localStorage.getItem("refresh_token");
await AdminIndex.hasAccess(access_token, refresh_token);
return config;
},
(error) => {
return Promise.reject(error);
}
);
store.subscribe(() => {
stateLoader.saveState(store.getState());
});
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
我认为 axios 拦截器存在一些问题。因为当我启动应用程序并输入登录凭据时,应用程序显示错误的用户名和密码等。我想知道问题是否是因为我们的应用程序使用的是 fetch 方法而不是 axios?因为我们正在尝试为获取 http 调用实现 axios 拦截器。仅对于登录代码,我们已应用 axios 对用户进行身份验证。下面是login的handleSubmit函数:
const handleSubmit = async (e) => {
e.preventDefault();
axios({
method: "post",
url: "/superuser/login",
headers: {
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
},
data: `username=${values.username}&useremail=${values.useremail}`,
})
.then((res) => {
const { access_token, refresh_token } = res.data;
Cookies.set("access", access_token);
localStorage.setItem("refresh_token", refresh_token);
props.set_login(res.data.access_token);
history.push("/admin/panel/papers");
})
.catch((err) => setDialogStatus(true));
};
请查看是什么导致无法登录应用程序的错误。如果我删除拦截器,应用程序会成功登录,但是当 access_token 过期时我将无法刷新它。在拦截器中,我将刷新 access_token 的功能放入应用程序的道具中。希望我已经清楚地说明了我的问题。但如果有什么遗漏,请不要屏蔽问题,只需添加评论,我会立即回复。
提前致谢!
没有! axios拦截器是axios的内部机制;这意味着,它只拦截由 axios 库本身发送的请求。如果我们想拦截 window.fetch 请求,我们需要为此设置自定义拦截器,例如,如果 api 的响应是 403 错误,则在 catch 块中进行过滤,然后执行特定操作。
但即便如此,最优选的方法是完全使用 axios 库并在整个项目中进行替换。
我们的 React 应用在其大部分或所有区域中使用 window.fetch 方法进行 http 调用。以前,它只有一个访问内容的令牌,而我们所做的是,我们在每个请求中单独添加一个 header,以发送令牌等。下面是此类请求的示例代码:
useEffect(() => {
// GET S3 CREDANTIONS
fetch("/dashboard/de/question/s3credentials", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${loginReducer}`,
},
})
但现在我们已经配置 api 访问两个令牌,一个用于访问内容,另一个用于刷新访问令牌。为此,在从互联网上搜索之后,我们决定添加一个 axios 拦截器,以在每次 http 调用之前检查 access_token 是否有效。 所以,我制作了拦截器并将其放在反应应用程序的 index.js 中。如果 access_token 有效,则在发送之前全局检查每个 http 请求;如果不是,请刷新。我从这个 link 得到了这个想法: https://blog.bitsrc.io/setting-up-axios-interceptors-for-all-http-calls-in-an-application-71bc2c636e4e 除了这个link,我还从包括Whosebug在内的许多其他网站上学习了它,并且我对它的理解更多,所以应用了它。 下面是 index.js 文件中的 axios 拦截器的代码(整体):
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import axios from "axios";
import AdminIndex from "./AdminPanel/Pages/AdminIndex";
import Cookies from "js-cookie";
// React Redux
import allReducers from "./reducers/index";
import { createStore } from "redux";
import { Provider } from "react-redux";
import StateLoader from "./reducers/PresistedState";
const stateLoader = new StateLoader();
let store = createStore(
allReducers,
stateLoader.loadState(),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
axios.interceptors.request.use(
async (config) => {
let serverCallUrl = new URL(config.url);
if (serverCallUrl.pathname.includes("/superuser/login")) return config;
let access_token = Cookies.get("access");
let refresh_token = localStorage.getItem("refresh_token");
await AdminIndex.hasAccess(access_token, refresh_token);
return config;
},
(error) => {
return Promise.reject(error);
}
);
store.subscribe(() => {
stateLoader.saveState(store.getState());
});
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
我认为 axios 拦截器存在一些问题。因为当我启动应用程序并输入登录凭据时,应用程序显示错误的用户名和密码等。我想知道问题是否是因为我们的应用程序使用的是 fetch 方法而不是 axios?因为我们正在尝试为获取 http 调用实现 axios 拦截器。仅对于登录代码,我们已应用 axios 对用户进行身份验证。下面是login的handleSubmit函数:
const handleSubmit = async (e) => {
e.preventDefault();
axios({
method: "post",
url: "/superuser/login",
headers: {
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
},
data: `username=${values.username}&useremail=${values.useremail}`,
})
.then((res) => {
const { access_token, refresh_token } = res.data;
Cookies.set("access", access_token);
localStorage.setItem("refresh_token", refresh_token);
props.set_login(res.data.access_token);
history.push("/admin/panel/papers");
})
.catch((err) => setDialogStatus(true));
};
请查看是什么导致无法登录应用程序的错误。如果我删除拦截器,应用程序会成功登录,但是当 access_token 过期时我将无法刷新它。在拦截器中,我将刷新 access_token 的功能放入应用程序的道具中。希望我已经清楚地说明了我的问题。但如果有什么遗漏,请不要屏蔽问题,只需添加评论,我会立即回复。 提前致谢!
没有! axios拦截器是axios的内部机制;这意味着,它只拦截由 axios 库本身发送的请求。如果我们想拦截 window.fetch 请求,我们需要为此设置自定义拦截器,例如,如果 api 的响应是 403 错误,则在 catch 块中进行过滤,然后执行特定操作。 但即便如此,最优选的方法是完全使用 axios 库并在整个项目中进行替换。