You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firefox中fetch API二次请求未等首次响应致custombackendtoken缺失

Firefox下请求未携带预期Token的排查思路

问题现象

调用fetchData方法时,Firefox中部分二次请求未携带custombackendtoken请求头,Chrome无此问题。服务器日志显示请求顺序为:request1(获取Token的请求)输入、request2(业务请求)输入、request2输出、request1输出,确认二次请求确实未携带目标头,多次刷新页面可复现该异常。

排查思路

  • 排查异步竞态问题
    从日志顺序看,request2在request1的响应返回前就已发起,说明getAuthToken内的异步操作未正确阻塞二次请求。需确认retrieveStoredToken或createToken是否存在未正确await的异步逻辑,或是Firefox下缓存/存储逻辑出现竞态,导致bearerToken未就绪就执行了二次请求。

  • 验证Headers对象兼容性
    Firefox对RequestInit.headers的处理可能与Chrome存在差异,直接解构对象赋值可能引发异常。尝试改用Headers API构建请求头:

    const reqOptions: RequestInit = options || {};
    reqOptions.headers = new Headers(reqOptions.headers);
    reqOptions.headers.set('custombackendtoken', bearerToken);
    
  • 调整Firefox缓存策略
    retrieveStoredToken通过请求${proxyPath}/token获取缓存Token,Firefox的缓存优先级可能更高,导致retrieveStoredToken返回undefined的时机与Chrome不一致,触发createToken异步流程时二次请求已发起。可添加缓存禁用参数:

    const response = await fetch(`${proxyPath}/token`, {
      credentials: 'same-origin',
      cache: 'no-store'
    });
    
  • 添加调试日志定位时机
    在getAuthToken的关键节点(进入函数、retrieveStoredToken返回后、createToken返回后、最终return前)添加日志,同时在fetchData中记录bearerToken值和二次请求发起时间,对比Firefox与Chrome的日志差异,确认Token是否在二次请求发起前已正确获取。

  • 检查Firefox隐私安全设置
    Firefox的隐私模式、跟踪保护或第三方Cookie设置可能影响retrieveStoredToken请求的Credentials传递,导致无法获取缓存Token。测试关闭隐私模式或调整安全设置后是否仍复现问题。

相关代码

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

内容的提问来源于stack exchange,提问作者Musti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:05:06