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

Node.js调用Twitch接口校验用户名解析body时触发TypeError报错

报错根因
  • 未声明请求方法:request库默认发送GET请求,而Twitch GQL接口仅接受POST请求,接口返回的根本不是预期的GQL响应数组,直接读取body[0]得到undefined,再往下读取data属性就会抛出类型错误。
  • 无错误兜底逻辑:没有处理请求报错、HTTP非200状态、JSON解析失败、字段不存在的场景,只要任意一步不符合预期就会直接抛错。
  • 异步逻辑写法错误:在request的异步回调里return值,外层getUser函数是同步执行逻辑,根本拿不到回调里的返回结果。
  • 请求体构造不规范:手动拼接JSON字符串,一旦用户名包含引号等特殊字符,会直接破坏请求体JSON结构,导致接口返回错误。
  • 业务判断逻辑错误:Twitch接口对不存在的用户名返回的data.user值为null,并非id等于0,原判断条件永远不会触发无效用户名的分支。
修复后代码
// 注:request库已停止维护,后续可替换为undici、axios、node-fetch等现代请求库,以下代码基于你现有依赖修改
function getUser(username) {
  return new Promise((resolve, reject) => {
    const opts = {
      url: "https://gql.twitch.tv/gql",
      method: "POST", // 补全必须的POST请求方法
      headers: {
        'Connection': 'keep-alive',
        'Pragma': 'no-cache',
        'Cache-Control': 'no-cache',
        'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"',
        'Accept-Language': 'en-US',
        'sec-ch-ua-mobile': '?0',
        'Client-Version': '7b9843d8-1916-4c86-aeb3-7850e2896464',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36',
        'Content-Type': 'application/json', // 替换为标准JSON请求头
        'Client-Session-Id': '51789c1a5bf92c65',
        'Client-Id': 'kimne78kx3ncx6brgo4mv6wki5h1ko',
        'X-Device-Id': 'xH9DusxeZ5JEV7wvmL8ODHLkDcg08Hgr',
        'sec-ch-ua-platform': '"Windows"',
        'Accept': '*/*',
        'Origin': 'https://www.twitch.tv',
        'Sec-Fetch-Site': 'same-site',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Dest': 'empty',
        'Referer': 'https://www.twitch.tv/',
      },
      // 用JSON.stringify序列化请求体,避免手动拼接字符串导致的结构错误
      body: JSON.stringify([{
        operationName: "WatchTrackQuery",
        variables: {
          channelLogin: username,
          videoID: null,
          hasVideoID: false
        },
        extensions: {
          persistedQuery: {
            version: 1,
            sha256Hash: "38bbbbd9ae2e0150f335e208b05cf09978e542b464a78c2d4952673cd02ea42b"
          }
        }
      }])
    }

    request(opts, (err, res, body) => {
      // 先处理请求层错误
      if (err) return reject(new Error(`请求失败: ${err.message}`));
      if (res.statusCode !== 200) return reject(new Error(`接口异常,状态码: ${res.statusCode}`));

      // 加JSON解析容错,避免接口返回非JSON内容时报错
      let parsedRes;
      try {
        parsedRes = JSON.parse(body);
      } catch (parseErr) {
        return reject(new Error(`响应解析失败: ${parseErr.message}`));
      }

      // 用可选链逐层读取字段,避免undefined读属性的报错
      const userId = parsedRes?.[0]?.data?.user?.id;
      if (!userId) {
        resolve("Invalid Username");
      } else {
        resolve(userId);
      }
    });
  });
}

// 调用示例(异步函数内可加await使用)
// getUser("目标用户名")
//   .then(result => console.log("校验结果:", result))
//   .catch(error => console.error("校验出错:", error))
注意事项
  • 异步函数必须通过Promise、回调或者async/await的方式获取结果,不要试图在异步回调里return给外层同步函数拿值。
  • 所有外部接口返回的数据都必须做存在性校验,不要默认接口永远返回你预期的结构,网络波动、接口变更、参数错误都可能导致返回结构变化。
  • 构造JSON格式的请求体时,永远用JSON.stringify方法序列化,不要手动拼接字符串,避免特殊字符转义问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:39:18