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

NodeJS读取JSON数据调用天气API出现JSON.parse错误如何解决

问题原因

你遇到的SyntaxError: Unexpected token in JSON at position 0错误,核心是JSON.parse接收到的内容不是合法JSON格式,首个字符就不符合JSON语法规范,对应你给出的代码场景,有几个常见的触发原因和修复方案:

修复方案

1. 处理JSON文件BOM头问题

绝大多数这类首字符解析错误都是UTF-8格式的JSON文件携带了BOM(字节顺序标记)导致的,Windows平台的编辑器保存文件时经常默认添加BOM,这个不可见的标记会被识别为位置0的非法字符。
直接修改解析逻辑即可,将代码里的

data2 = JSON.parse(data);

替换为:

// 先移除可能存在的BOM头再解析
data2 = JSON.parse(data.replace(/^\uFEFF/, ''));

也可以直接用编辑器将JSON文件另存为「UTF-8 无BOM」格式,从根源解决问题。

2. 排查文件读取异常

在解析前添加日志确认读取到的内容是否正确,避免因为路径错误读取到空内容或者其他文件的内容:

if(err) throw err;
// 新增日志确认读取内容
console.log('读取到的文件内容:', data);
data2 = JSON.parse(data.replace(/^\uFEFF/, ''));

如果日志输出为空或者和你写的JSON内容不符,说明文件路径配置错误:NodeJS里相对路径是相对于执行node命令的工作目录,而非JS文件所在目录,建议换成绝对路径读取:

// 先引入path模块
const path = require('path');
// 读取时用绝对路径
fs.readFile(path.resolve(__dirname, './json/data.json'),"utf8", function (err, data) {
  // 原有逻辑
})

3. 修复代码里的其他逻辑问题

你当前的代码还有异步处理、API返回值解析的问题,建议一并修复:

  • 你用了async声明函数,但全程没有用await处理异步逻辑,最后console.log(lstValid)执行时,文件还没读取完成、API请求也没有返回,所以你会先看到空数组[]的输出
  • OpenWeatherMap的返回结果里weather字段是数组,你写的data.weather.description会取值失败,要改成data.weather[0].description

修正后的参考代码:

const fs = require('fs/promises'); // 改用 promise 版的fs模块更适配async语法
const path = require('path');

async function calcWeather() {
  const lstValid = [];
  try {
    // await 等待文件读取完成
    const data = await fs.readFile(path.resolve(__dirname, './json/data.json'), 'utf8');
    const data2 = JSON.parse(data.replace(/^\uFEFF/, ''));
    
    // 等待所有API请求完成
    const requestPromises = data2.map(async item => {
      const base = `https://api.openweathermap.org/data/2.5/weather?lat=${item.latjson}&lon=${item.lonjson}&appid=${api_key}&units=metric&lang=sp`;
      const response = await fetch(base);
      const weatherData = await response.json();
      
      const myObject = {
        Id_Oficina: item.IdOficina,
        Humedad: weatherData.main.humidity,
        Nubes: weatherData.clouds.all,
        Sensacion: weatherData.main.feels_like,
        Temperatura: weatherData.main.temp,
        Descripcion: weatherData.weather[0].description, // 修正weather字段取值
      };
      
      if (myObject.Temperatura < 99) {
        lstValid.push(myObject);
      }
    });
    
    await Promise.all(requestPromises);
    console.log(lstValid); // 所有请求完成后再输出结果
    return lstValid;
  } catch (err) {
    console.error('处理失败:', err);
    throw err;
  }
}

内容的提问来源于stack exchange,提问作者Martín JF

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:36:09