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

页面加载时从JSON读取车站数据到数组后无法正常显示的问题

问题:页面加载/重载时无法正常显示车站全名

开发展示预选车站发车信息的Web应用,选中车站ID存储在cookie中。将包含车站ID与全名的JSON文件读取到数组Stations,以ID为键、全名为值存储(Stations[Id] = FullName)。目前存在以下问题:

  • 控制台输出Stations数据正常,但页面打开或重载时,checkCookie()函数在页面上显示undefined而非车站名称
  • 选择新车站并执行setCookie()函数后,车站全名可正常显示
  • 已尝试将checkCookie()设为async并等待loadStations()完成,问题仍未解决

原代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>

var Stations = [];

function onLoad() {
    checkCookie();
    return;
}

async function loadStations() {
    fetch("tinystations.json")
        .then(response => response.json())
        .then(stations => stations.forEach(item => 
            Stations[item.Id] = item.FullName));
        return;
}

async function checkCookie() {
    await loadStations();
    console.log(Stations);
    var station1 = getCookie("station1");
    document.getElementById("chosen1").innerHTML = station1 + " : " + Stations[station1];
    return;
}

function setCookie() {
    const d = new Date();
    d.setTime(d.getTime() + 100000000000); // Sufficiant amount of time. 3 years.
    let expires = "expires=" + d.toUTCString();
    let station1 = document.getElementById("TIstation1").value;
    document.cookie = "station1=" + station1 + ";" + expires;
    document.getElementById("chosen1").innerHTML = station1 + " : " + Stations[station1];
    return;
}

function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}
</script>
</head>
<body onload="onLoad()">
    <div id="coockie">
        <p>Select new stations</p>
        <input id="TIstation1" type="text" placeholder="Choose station" />
        <button onclick="setCookie()">Save</button>
    </div>
    <div id="chosen">
        Preselected:
        <p id="chosen1"> </p>
    </div>
</body>
</html>

JSON文件内容

[
    {
        "FullName": "Arlanda C",
        "Id": "Arnc"
    },
    {
        "FullName": "Huddinge",
        "Id": "Hu"
    },
    {
        "FullName": "Jakobsberg",
        "Id": "Jkb"
    },
    {
        "FullName": "Stuvsta",
        "Id": "Stu"
    },
    {
        "FullName": "Rotebro",
        "Id": "R"
    },
    {
        "FullName": "Stockholm City",
        "Id": "Sci"
    }
]

问题原因与修复方案

核心问题

loadStations函数标记为async,但内部的fetch调用没有返回Promise,导致await loadStations()无法真正等待JSON数据加载完成。checkCookie会在Stations还未填充数据时就执行DOM更新,因此显示undefined。

修复步骤

  1. 让loadStations返回Promise:修改函数使其返回fetch的Promise链,确保await能正确等待数据加载完成。
  2. 将Stations改为对象(可选但更合理):因为使用字符串作为键,对象比数组更符合键值对的语义,避免数组索引混淆问题。
  3. 增加空值判断:避免cookie不存在或车站ID无效时显示异常内容。

修改后的完整代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
// 改为对象存储键值对更合理
var Stations = {};

function onLoad() {
    checkCookie();
}

async function loadStations() {
    // 返回fetch的Promise链,让await能正确等待数据加载
    return fetch("tinystations.json")
        .then(response => {
            // 增加请求错误处理
            if (!response.ok) throw new Error("车站数据加载失败");
            return response.json();
        })
        .then(stations => stations.forEach(item => 
            Stations[item.Id] = item.FullName))
        .catch(err => console.error(err));
}

async function checkCookie() {
    await loadStations();
    console.log(Stations);
    var station1 = getCookie("station1");
    // 增加空值判断,优化显示
    if (station1 && Stations[station1]) {
        document.getElementById("chosen1").innerHTML = `${station1} : ${Stations[station1]}`;
    } else {
        document.getElementById("chosen1").innerHTML = station1 ? `无效车站ID: ${station1}` : "未选择车站";
    }
}

function setCookie() {
    const d = new Date();
    d.setTime(d.getTime() + 100000000000); // 约3年有效期
    let expires = "expires=" + d.toUTCString();
    let station1 = document.getElementById("TIstation1").value;
    document.cookie = "station1=" + station1 + ";" + expires;
    document.getElementById("chosen1").innerHTML = station1 + " : " + (Stations[station1] || "无效车站ID");
}

function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}
</script>
</head>
<body onload="onLoad()">
    <div id="coockie">
        <p>Select new stations</p>
        <input id="TIstation1" type="text" placeholder="Choose station" />
        <button onclick="setCookie()">Save</button>
    </div>
    <div id="chosen">
        Preselected:
        <p id="chosen1"> </p>
    </div>
</body>
</html>

额外说明

  • 新增的错误处理可以在网络请求失败时在控制台输出提示,便于调试
  • 空值判断提升了用户体验,避免页面显示无意义的undefined
  • 使用对象存储车站数据,更符合键值对的使用场景,代码语义更清晰

内容的提问来源于stack exchange,提问作者Clas Östman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:24:57