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

循环调用返回JSON的API接口时程序中途报错,请求排查解决

解决批量请求JSON解析失败的问题

嘿,我看你遇到的这个SyntaxError: Unexpected token...问题,本质是某个请求返回的内容不是合法JSON,导致JSON.parse(body)直接报错。结合你一次性发起1000个请求的场景,大概率是这几个原因,咱们一步步来解决:

1. 并发请求太猛被服务器限流了

你用同步循环发起异步请求,相当于瞬间给服务器打了1000个请求,几乎所有后端都会有并发限制,超过阈值后会返回429(请求过多)、503这类错误响应——这些响应通常是HTML错误页或者纯文本,根本不是JSON,解析肯定失败。

怎么改?控制并发数

别一次性发所有请求,改成串行或者限制同时发起的请求数。比如用p-limit(Node.js环境)来控并发,代码示例如下:

// 先装依赖:npm i p-limit
const pLimit = require('p-limit');
const limit = pLimit(10); // 限制同时跑10个请求,数字可以根据服务器承受力调整

const fetchIssueCounts = async () => {
  // 把每个请求包装成受限制的异步函数
  const requestPromises = Keys.map(key => limit(async () => {
    try {
      // 把回调式的httpRequest封装成Promise版本
      const res = await new Promise((resolve, reject) => {
        httpRequest(`https://hostname/api/issues/projectKeys=${key}?format=jSON`)
          .auth(global.username, global.password)
          .end((err, res) => err ? reject(err) : resolve(res));
      });

      // 先校验状态码
      if (res.statusCode !== 200) throw new Error(`状态码错误: ${res.statusCode}`);
      
      const jsonObj = JSON.parse(res.body);
      return jsonObj.total;
    } catch (err) {
      console.error(`处理密钥 ${key} 时出错:`, err.message);
      return null; // 出错就返回null,后续过滤掉
    }
  }));

  // 等待所有请求完成
  const issueCounts = await Promise.all(requestPromises);
  // 过滤无效数据
  const validCounts = issueCounts.filter(count => count !== null);
  console.log(`成功获取 ${validCounts.length} 条有效数据`);
};

fetchIssueCounts();

要是不想用第三方库,写个简单的串行循环也能搞定:

let currentIndex = 0;
const issue = [];

function fetchNextKey() {
  if (currentIndex >= Keys.length) {
    console.log('所有请求完成!共获取', issue.length, '条数据');
    return;
  }

  const key = Keys[currentIndex];
  currentIndex++;

  httpRequest(`https://hostname/api/issues/projectKeys=${key}?format=jSON`, function (err, res, body) {
    // 先处理请求错误
    if (err) {
      console.error(`请求密钥 ${key} 失败:`, err);
      fetchNextKey();
      return;
    }

    // 校验响应状态码
    if (res.statusCode < 200 || res.statusCode >= 300) {
      console.error(`密钥 ${key} 返回错误状态码: ${res.statusCode},响应内容:`, body);
      fetchNextKey();
      return;
    }

    // 包裹try-catch处理解析错误
    try {
      const jsonObj = JSON.parse(body);
      issue.push(jsonObj.total);
      console.log('当前已获取', issue.length, '条数据');
    } catch (parseErr) {
      console.error(`解析密钥 ${key} 的响应失败:`, parseErr.message);
      console.log('原始响应内容:', body); // 打印出来方便排查问题
    }

    // 发起下一个请求
    fetchNextKey();
  }).auth(global.username, global.password);
}

// 启动串行请求
fetchNextKey();

2. 单个密钥无效/权限不足,返回非JSON内容

有些密钥可能本身就无效,或者你没有访问对应项目的权限,API返回的是错误提示(比如HTML页面、纯文本),不是合法JSON,自然解析失败。

怎么改?加完整的错误处理和校验

刚才的代码已经包含了这些关键处理:

  • 先判断err是否存在,处理请求层面的错误
  • 检查响应状态码,只在成功状态下解析JSON
  • 给JSON.parse套try-catch,捕获解析错误,同时打印对应密钥和响应内容,方便定位哪个密钥出问题

另外还要注意var i的闭包陷阱!你原来的代码用var i,循环里的所有回调共享同一个i变量,当回调执行时i已经变成1000了,导致你根本不知道是哪个密钥出问题。改成let i或者把key存到局部变量里(比如上面代码里的const key = Keys[currentIndex])就能解决。

3. URL参数可能写错了?

你URL里的format=jSON,有些API对参数大小写敏感,是不是应该写成format=json?可以看看API文档确认下,要是参数写错了,API可能返回非JSON内容。


总结下核心要点:

  • 控制并发数,别把服务器怼懵了
  • 完善错误处理,每个环节都做校验
  • 修复闭包陷阱,确保每个请求对应正确的密钥

内容的提问来源于stack exchange,提问作者Mudabbir Pasha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:59:01