我在 Firefox 中有一个非常奇怪的行为。 代码如下所示。 一旦第一个请求的响应返回,标头就会被丰富并发送第二个请求。但我在服务器日志中看到有时请求(第二个请求)不包含令牌(custombackendtoken)。怎么会这样?
您可以通过重新加载页面在 Firefox 中重现该问题。当页面加载或第一个请求运行时(通过多次尝试刷新)。
在chrome中不会出现同样的情况。 如果没有custombackendtoken header,第二个请求如何到达后端?
我还通过标头转储检查了服务器日志,第二个请求显然是由浏览器发送的,没有预期的标头。 顺序是这样的: 请求1输入 请求2输入 请求2输出 请求1输出
如果有人有想法,我将非常感激。
export const fetchData = async (input: RequestInfo, options?: RequestInit, proxyPath?: string): Promise<Response> => {
try {
// first request
const bearerToken = await getAuthToken(proxyPath);
const reqOptions: RequestInit = options || {};
reqOptions.headers = {
...reqOptions.headers,
custombackendtoken: bearerToken,
};
// second request
return await fetch(input, reqOptions);
} catch (e) {
console.error('Error.......', e);
throw new Error(`Error....... Error: ${e}`);
}
};
//getAuthToken
export default async (proxyPath: string): Promise<string> => {
let token = await retrieveStoredToken(proxyPath);
if (!token) {
token = await createToken();
if (!token) {
throw new Error('Token can not be created!');
}
storeToken(proxyPath, token);
}
return token;
};
//retrieveStoredToken
const retrieveStoredToken = async (proxyPath: string): Promise<string | undefined> => {
try {
const response = await fetch(`${proxyPath}/token`, {
credentials: 'same-origin',
});
return await response.json();
} catch (e) {
console.error('Error ..........', e);
}
return undefined;
};
只是猜测,但它可能与 Firefox 中的一个旧错误有关,该错误导致无法正确处理中止的请求:https://bugzilla.mozilla.org/show_bug.cgi?id=1583815
不幸的是,这个错误已经存在很多年了,而且似乎从未得到修复。
如果此错误是您在服务器日志中看到的偶尔问题的原因,则在此讨论中提供了有关如何解决此问题的提示:https://github.com/Yaffle/EventSource/issues/130 #issuecomment-535862539
基本上,您将在获取数据时提供 AbortController 信号,用它来识别中止的请求,然后处理这种情况:
var controller = new AbortController();
var signal = controller.signal;
fetch('data:text/plain,test', {signal}).then(function(response) {
if (signal?.aborted) {
const reader = response.body.getReader();
reader.cancel();
// ... handle the aborted request, prevent the follow-up request etc.
}
})