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

Node.js调用Marvel API时JSON.parse报Unexpected end of JSON input错误

问题现象

在Node.js环境下调用Marvel API获取数据,使用JSON.parse()解析接口返回内容时持续失败,终端抛出SyntaxError: Unexpected end of JSON input类型错误。
错误触发位置为IncomingMessage的data事件回调中执行JSON.parse的代码行,对应本地项目app.js文件的第79行第24列。

原有调用代码

app.post("/", function(req, res) {
  const nameStartsWith = req.body.superhero;
  const ts = "timestamp";
  const apikey = "myPublicKey";
  const hash = "md5 digest";
  const url = "http://gateway.marvel.com/v1/public/characters?ts=" + ts + 
              "&apikey=" + apikey + "&hash=" + hash + "&nameStartsWith=" 
              + nameStartsWith;

  http.get(url, function(response) {

    response.on("data", function(data) {
      // 此处抛出解析错误
      console.log(JSON.parse(data));
    });
  });
});

异常表现

当前接口返回的内容为截断的不完整JSON片段,示例如下:

{"code":200,"status":"Ok","copyright":"© 2022 MARVEL","attributionText":"Data provided by Marvel. © 2022 MARVEL","attributionHTML":"<a href=\"http://marvel.com\">Data provided by Marvel. © 2022 MARVEL</a>","etag":"08aea880d9e638f37cf6011d63a936fbe3f82f22","data":{"offset":0,"limit":20,"total":5,"count":5,"results":[{"id":1009718,"name":"Wolverine","description":"Born with super-human senses and the power to heal from almost any wound, Wolverine was captured by a secret Canadian organization and given an unbreakable skeleton and claws. Treated like an animal, it took years for him to control himself. Now, he's a premiere member of both the X-Men and the Avengers.","modified":"2016-05-02T12:21:44-0400","thumbnail":{"path":"http://i.annihil.us/u/prod/marvel/i/mg/2/60/537bcaef0f6cf","extension":"jpg"},"resourceURI":"http://gateway.marvel.com/v1/public/characters/1009718","comics":{"available":2549,"collectionURI":"http://gateway.marvel.com/v1/public/characters/1009718/comics","items":[{"resourceURI":"http://gateway.marvel.com/v1/public/comics/41113","name":"5 Ronin (Hardcover)"},{"resourceURI":"http://gateway.marvel.com/v1/public/comics/38756","name":"5 Ronin (2010) #1"

终端输出的完整错误栈:

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at IncomingMessage.<anonymous> (C:\Users\mishr\OneDrive\Desktop\MarvelComics-Project\app.js:79:24)
错误原因

Node.js中HTTP响应的data事件是分块触发的:响应数据体积较大时,会被拆分成多个数据块传输,每收到一个块就会触发一次data事件,此时回调里拿到的data只是完整响应的一个片段,不是完整的JSON结构。直接对截断的片段执行JSON.parse,就会抛出“JSON输入意外结束”的语法错误,拿到的返回内容在"5 Ronin (2010) #1"处截断就是最直接的证据。

修复方案

需要先收集所有传输过来的数据块,等所有数据接收完成(触发end事件)后,再把拼接好的完整字符串做JSON解析,修复后的代码如下:

app.post("/", function(req, res) {
  const nameStartsWith = req.body.superhero;
  const ts = "timestamp";
  const apikey = "myPublicKey";
  const hash = "md5 digest";
  const url = "http://gateway.marvel.com/v1/public/characters?ts=" + ts + 
              "&apikey=" + apikey + "&hash=" + hash + "&nameStartsWith=" 
              + nameStartsWith;

  http.get(url, function(response) {
    // 初始化变量存储所有数据块
    let rawData = '';
    // 设置编码,自动将Buffer类型的块转为utf8字符串
    response.setEncoding('utf8');
    
    // 每收到一个数据块就拼接到rawData中
    response.on("data", function(chunk) {
      rawData += chunk;
    });

    // 所有数据接收完成后再执行解析
    response.on("end", function() {
      try {
        const apiResult = JSON.parse(rawData);
        console.log(apiResult);
        // 后续业务逻辑,比如把结果返回给前端
        res.send(apiResult);
      } catch (parseError) {
        // 捕获解析异常,避免服务崩溃
        console.error("JSON解析失败:", parseError);
        res.status(500).send("接口数据解析异常");
      }
    });

    // 监听请求层面的错误
    response.on("error", function(err) {
      console.error("请求Marvel接口失败:", err);
      res.status(500).send("接口请求失败");
    })
  });
});

注意事项

  • 永远不要在data事件回调中直接对响应内容做完整JSON解析,该事件触发时数据大概率还没传输完成
  • 解析JSON时建议包裹try/catch,避免接口返回非JSON格式内容(比如网关报错页、空响应)时导致服务进程崩溃
  • 建议同时监听响应的error事件,处理网络中断、超时等请求层面的异常

内容的提问来源于stack exchange,提问作者Satyam Adarsh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:45:16