Node.js获取指定URL JSON解析失败,Chrome DevTools可正常运行求解答
为什么Chrome能正常解析但Node.js里JSON解析失败?
问题根源
浏览器发起fetch请求时,会自动附带一系列浏览器环境特有的请求头——比如User-Agent会告诉服务器"我是Chrome浏览器",Accept会明确指定我要JSON格式的响应。服务器识别到这些标识后,会返回格式干净的JSON数据。
但Node.js环境下的node-fetch和request-promise-native默认请求头非常简洁,没有这些浏览器专属标识,服务器可能把它当成非浏览器的脚本/爬虫请求,返回的内容要么带有字节顺序标记(BOM)、多余换行符,甚至可能是伪装成JSON的错误页面,这就直接导致解析时触发Unexpected token in JSON at position 0错误。
解决办法:模拟浏览器请求头
只需要在请求中添加浏览器常用的请求头,就能让服务器返回正确的JSON数据,下面是两种工具的修正方案:
1. node-fetch 版本
const fetch = require("node-fetch"); async function fetchCharityData() { const url = "https://beta.charitycommission.gov.uk/umbraco/api/charityApi/getSearchResults?searchText=&pageNumber=1&contextId=1126&onlyShow="; // 模拟Chrome浏览器的请求头 const requestHeaders = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "Accept": "application/json, text/javascript, */*; q=0.01" }; try { const response = await fetch(url, { headers: requestHeaders }); // 先确认响应状态正常 if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`); const jsonData = await response.json(); console.log(jsonData.pageItems); } catch (error) { console.error("出错了:", error); } } fetchCharityData();
2. request-promise-native 版本
这里可以直接开启json: true让库自动帮你解析JSON,省去手动处理字符串的麻烦:
const rp = require('request-promise-native'); async function fetchCharityData() { const url = "https://beta.charitycommission.gov.uk/umbraco/api/charityApi/getSearchResults?searchText=&pageNumber=1&contextId=1126&onlyShow="; const requestOptions = { uri: url, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "Accept": "application/json, text/javascript, */*; q=0.01" }, json: true // 自动解析JSON,无需手动调用JSON.parse }; try { const data = await rp(requestOptions); console.log(data.pageItems); } catch (error) { console.error("出错了:", error); } } fetchCharityData();
小提示
- 你原URL里有一堆重复的
&符号,可以简化成?searchText=&pageNumber=1&contextId=1126&onlyShow=,完全不影响请求效果。 - 如果还是出现解析错误,可以先把响应内容转成纯文本打印出来(比如node-fetch用
await response.text()代替response.json()),看看服务器到底返回了什么——大概率会发现是错误页面的HTML,这时候就能更精准地调整请求头了。
内容的提问来源于stack exchange,提问作者Max888
相关产品推荐
相关产品推荐

