【问题标题】:processing json with fetch returns undefined for valid json key使用 fetch 处理 json 返回未定义的有效 json 键
【发布时间】:2026-01-15 03:00:01
【问题描述】:

我需要从我的 REST 服务器请求数据来填充我的 UI(前端)。为此,我需要从我的服务器和其他服务器请求一些数据。一个这样的请求是获取州(省)列表,处理每个州并将它们添加到select HTML 组件。我使用 fetch().json() 以及其他工具来执行此操作。

问题:

在调用我的 REST 服务器获取 json 数据时,我收到以下数据(取自 Chrome 控制台):

{provinces:[Eastern Cape,Mpumalanga,Western Cape,Gauteng,KwaZulu Natal,North West,Northern Cape,Free 
State,Limpopo]}

我打算将这些中的每一个作为选项添加到select。在尝试获取 provinces 键的值时,我得到了 undefined

我正在拨打这个电话:

fetch("http://localhost:3443/app/location/provinces").then(e => e.json()).then(e => console.log(e.provinces));

此外,由于我可以使用 [] 运算符直接引用 json 键,因此我尝试使用

fetch("http://localhost:3443/app/location/provinces").then(e => e.json()).then(e => console.log(e['provinces']));

您可能已经猜到了,它也返回 undefined。

为了记录,完整的 Chrome 控制台输出是

Promise {<pending>}
undefined

查看一些 SO 示例,我相信我的调用可能是正确的,onethisthis 一个都证实了它的有效性。

我还尝试了什么:

SO postthis one 建议在同一 then() 调用中使用 json 数据响应,例如

fetch("http://localhost:3443/app/location/provinces").then(e => {
    e.json().then(s => {
        console.log(s['provinces']);
 });
});

fetch("http://localhost:3443/app/location/provinces").then(e => {
    e.json().then(s => {
        console.log(s.provinces);
 });
});

两者都返回:

Promise {<pending>}
undefined

我错过了什么/做错了什么?


更新

按上述命令顺序排列的 Chrome 控制台屏幕截图:

资源文件 za-province-city.json

NodeJS 快递代码:

const express = require('express');
const router = express.Router();
const fs = require('fs');
const raw = fs.readFileSync("./res/za-province-city.json");
const map = JSON.parse(raw);
const mapProvinceCity = {};
map.forEach(item => {
    if (!mapProvinceCity.hasOwnProperty(item.ProvinceName)) {
        mapProvinceCity[item.ProvinceName] = [];
    }
    mapProvinceCity[item.ProvinceName].push(item.City);
});
for (let key in mapProvinceCity) {
    mapProvinceCity[key].sort((a, b) => a.toLocaleString().localeCompare(b.toLowerCase()));
}

router.get('/location/provinces', function (req, res, next) {
    let strings = Object.keys(mapProvinceCity);
    let json = JSON.stringify({provinces: strings}).replace(/"/g, '');
    return res.json(json);
});

router.get('/location/:province/cities', function (req, res, next) {
    let province = req.param('province');
    let cities = mapProvinceCity[province];
    let json = JSON.stringify({cities: cities}).replace(/"/g, '');
    return res.json(json);
});

module.exports = router;

注意:如果您想知道replace(),每次我在邮递员中请求数据时,都会得到

【问题讨论】:

  • “我收到以下数据(取自 Chrome 控制台)” ????在哪里?哪个特定的 console.log() 行产生了该结果?
  • 您返回的数据是否与此处包含的数据完全一致?因为那不是有效的json。 (没有引号。)如果这是从服务器返回的,e.json() 调用可能正在抛出。
  • @Phil 添加截图,请稍等
  • @rayhatfield 见上面的评论
  • 你到底在用那个字符串替换做什么?此外,您正在对损坏的 JSON 进行双重编码,因此最终它只是一个不可用的字符串。只需使用res.json({provinces: strings})

标签: javascript node.js json express fetch


【解决方案1】:

我认为您的问题都源于对 Express'res.json() 的误解。

这基本上是一个快捷方式

res.set("Content-type: application/json")
res.status(200).send(JSON.stringify(data))

我想你的问题始于你认为你需要stringify你的数据。然后发生的是您的数据是双重编码/双重字符串化的,因此是额外的引号。删除引号会破坏您的数据。

console.log() 不是一个特别好的调试工具,因为它混淆了很多信息。在您的代码中,s 实际上是一个字符串

"{provinces:[Eastern Cape,Mpumalanga,...]}"

我建议你改用实际的debugger


简单的解决方案是按预期使用res.json()

router.get('/location/provinces', function (req, res, next) {
  return res.json({ provinces: Object.keys(mapProvinceCity) });
});

你的客户端代码看起来像

fetch("http://localhost:3443/app/location/provinces")
  .then(res => {
    if (!res.ok) {
      throw res
    }
    return res.json()
  })
  .then(data => {
    console.log('Provinces:', data.provinces)
  })

这适用于您的所有 Express 路线。不要不要使用JSON.stringify()

【讨论】:

  • 您对 res.json() 作为标题的快捷方式等是正确的。我记得不久前经历过。希望这一切很快就会回到我身边:)
最近更新 更多