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

若浏览器存在session变量,如何避免重复发起fetch请求?

问题分析

你的代码出现阻塞/报错的核心原因有两个:

  1. 变量作用域问题:phoneNum仅在if (!sessionStorage.getItem("country_code"))的代码块内定义,当session中已有country_code时,外部的await phoneNum.json()会触发phoneNum is not defined的错误,导致后续逻辑中断。
  2. 逻辑分支缺失:你没有处理“已有缓存的国家码时,如何获取电话数据”的分支,要么需要缓存电话数据,要么按需发起必要的请求。
修正方案

根据你“避免不必要API调用”的需求,提供两种常见场景的解决方案:

场景1:电话数据无需实时更新,可缓存到sessionStorage

如果/contacts/接口返回的是所有国家的电话列表且不需要实时刷新,可以把电话数据也缓存起来,彻底避免重复请求:

async function fetchCountryAndPhone() {
    // 先读取缓存的国家码和电话数据
    let countryCode = sessionStorage.getItem("country_code");
    let cachedPhone = sessionStorage.getItem("phone_data");

    // 没有国家码时,请求/userinfo/获取并存储
    if (!countryCode) {
        const countryRes = await fetch('/userinfo/');
        const country = await countryRes.json();
        countryCode = country.country_code.toLowerCase();
        sessionStorage.setItem("country_code", countryCode);
    }

    // 没有缓存的电话数据时,请求/contacts/获取并存储(转成字符串存入session)
    if (!cachedPhone) {
        const phoneRes = await fetch('/contacts/');
        const phoneData = await phoneRes.json();
        cachedPhone = JSON.stringify(phoneData);
        sessionStorage.setItem("phone_data", cachedPhone);
    }

    // 把缓存的电话数据转成JSON对象后返回
    return [JSON.parse(cachedPhone), countryCode];
}

fetchCountryAndPhone().then(([phone, countryCode]) => {
    const getContactNum = phone[countryCode].sales;
    // 这里写你的后续业务逻辑
}).catch(error => console.warn(error));

场景2:电话数据需要实时更新,仅缓存国家码

如果/contacts/返回的数据需要实时获取,只需要跳过/userinfo/的请求,保留必要的/contacts/请求:

async function fetchCountryAndPhone() {
    let countryCode = sessionStorage.getItem("country_code");

    // 没有国家码时才请求/userinfo/
    if (!countryCode) {
        const countryRes = await fetch('/userinfo/');
        const country = await countryRes.json();
        countryCode = country.country_code.toLowerCase();
        sessionStorage.setItem("country_code", countryCode);
    }

    // 实时请求最新的电话数据
    const phoneRes = await fetch('/contacts/');
    const phoneData = await phoneRes.json();

    return [phoneData, countryCode];
}

fetchCountryAndPhone().then(([phone, countryCode]) => {
    const getContactNum = phone[countryCode].sales;
    // 这里写你的后续业务逻辑
}).catch(error => console.warn(error));
关键修改说明
  • 提升变量作用域:将countryCode等变量放在函数顶部定义,避免块级作用域导致的未定义错误。
  • 拆分缓存逻辑:明确区分“可缓存的接口(/userinfo/)”和“需实时请求的接口(/contacts/)”,按需跳过不必要的请求。
  • 处理sessionStorage的字符串限制:sessionStorage只能存储字符串,因此缓存JSON数据时需用JSON.stringify转换,读取时用JSON.parse还原。
  • 简化后续逻辑:直接在函数内返回countryCode,避免在回调中重复读取sessionStorage,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:20:27