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

Node.js使用node-fetch读取本地JSON报ERR_INVALID_URL错误如何解决?

报错原因

Node环境下的fetch(包括你安装的node-fetch@3依赖)不支持直接传入相对路径读取本地文件,它仅支持http/https/file协议的合法URL,你传入./json/data.json相对路径无法被解析为合法URL,因此抛出ERR_INVALID_URL错误。

解决方案

方案1(推荐):使用原生fs模块读取本地JSON

读取本地文件无需额外引入fetch相关依赖,直接用Node内置的fs模块即可,ES模块(.mjs)环境下适配代码如下:

  1. 先导入依赖:
import { readFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
  1. 替换原有fetch读取JSON的代码:
// 构造当前文件所在目录路径,适配ES模块无__dirname的问题
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// 读取并解析JSON
const info = JSON.parse(await readFile(join(__dirname, './json/data.json'), 'utf8'));

方案2:仍使用fetch的适配方案

如果要继续用fetch读取本地文件,需要把相对路径转为合法的file协议URL:

const jsonFileUrl = new URL('./json/data.json', import.meta.url);
const info = await fetch(jsonFileUrl).then(res => res.json());

额外问题修正

你现有代码中循环内的天气接口请求是异步操作,循环结束后直接打印lstValid时,异步请求还未完成,会出现打印空数组的问题,可通过Promise.all等待所有请求完成后再操作,修正后的完整函数示例:

async function calcWeather() {
  // 构造目录路径、读取本地JSON
  const __filename = fileURLToPath(import.meta.url);
  const __dirname = dirname(__filename);
  const info = JSON.parse(await readFile(join(__dirname, './json/data.json'), 'utf8'));
  console.log(info);

  // 收集所有天气接口请求的Promise
  const requestTasks = info.map(async (item) => {
    const baseInfo = item[0];
    const base = `https://api.openweathermap.org/data/2.5/weather?lat=${baseInfo.latjson}&lon=${baseInfo.lonjson}&appid=${api_key}&units=metric&lang=sp`;
    const res = await fetch(base);
    const weatherData = await res.json();
    const myObject = {
      Id_Oficina: baseInfo.IdOficina,
      Humedad: weatherData.main.humidity,
      Nubes: weatherData.clouds.all,
      Sensacion: weatherData.main.feels_like,
      Temperatura: weatherData.main.temp,
      Descripcion: weatherData.weather[0].description,
    };
    return myObject.Temperatura < 99 ? myObject : null;
  });

  // 等待所有请求完成,过滤无效值得到最终有效数组
  const lstValid = (await Promise.all(requestTasks)).filter(Boolean);
  console.log(lstValid);
  // 此处可执行后续存入数据库的操作
}

内容的提问来源于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 01:45:04