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

Node.js调用YouTube API时JSON.parse解析数据致应用崩溃原因排查

问题

开发带搜索框的前端时,通过Node.js的https.get()调用YouTube API搜索视频,在response.on('data')回调里用JSON.parse()解析返回数据时应用崩溃,报错:

undefined:25 "url": "https://i.ytimg.com/vi/fWRISvAygU/ SyntaxError: Unexpected end of JSON input

同时控制台提示[nodemon] app crashed - waiting for file changes before starting...

已确认以下信息:

  • 相同URL在Postman中能获取完整JSON数据;
  • 前端传入的参数可正确拼接进请求URL;
  • https.get()返回状态码为200 OK;
  • 未解析的data为Buffer数据,且分为5个块(此前调用天气API时是单个Buffer块)。

相关代码:

const express = require("express");
const bodyParser = require("body-parser");
const https = require("https");
const Joi = require("joi");
const apiKey = "MyKeyWouldBeHere"; // 已隐藏密钥

const app = express();

app.use(bodyParser.urlencoded({extended:true}));
app.use(express.static("public"));

app.get("/", (req, res) => {
    res.sendFile(`${__dirname}/index.html`);
});

app.post("/videos", (req, res) => {
    const {error} = validation(req.body);
    if (error) return res.status(400).send("wrong way to write");

    const userInput = req.body.userInput;

    https.get(`https://www.googleapis.com/youtube/v3/search?part=snippet&key=${apiKey}&q=${userInput}`, (response) => {
        
        console.log(response.statusCode);

        response.on("data", function(data) {
            const weatherData = JSON.parse(data);
            console.log(data);

        });
    });
});

app.listen("3000", () => {
    console.log("Running server on port 3000");
});

function validation(value) {
    const schema = Joi.object({
        userInput: Joi.string().min(2).required()
    });
    return schema.validate(value);
}

解决方案

问题原因

https.get()的data事件是分块触发的,每次回调拿到的只是完整响应的一部分Buffer。直接对单个块执行JSON.parse(),相当于解析不完整的JSON片段,必然会抛出“Unexpected end of JSON input”错误。天气API返回数据量小,刚好在一个块里,所以之前没出问题,但YouTube API返回的数据更大,会被拆分成多个块传输。

修复步骤

  1. 声明变量拼接所有接收的Buffer块;
  2. 监听response的end事件(所有数据接收完成时触发),统一解析完整的JSON;
  3. 捕获解析错误,避免应用崩溃;
  4. 将处理后的数据返回给前端。

修复后的代码:

const express = require("express");
const bodyParser = require("body-parser");
const https = require("https");
const Joi = require("joi");
const apiKey = "MyKeyWouldBeHere"; // 已隐藏密钥

const app = express();

app.use(bodyParser.urlencoded({extended:true}));
app.use(express.static("public"));

app.get("/", (req, res) => {
    res.sendFile(`${__dirname}/index.html`);
});

app.post("/videos", (req, res) => {
    const {error} = validation(req.body);
    if (error) return res.status(400).send("wrong way to write");

    const userInput = req.body.userInput;

    https.get(`https://www.googleapis.com/youtube/v3/search?part=snippet&key=${apiKey}&q=${encodeURIComponent(userInput)}`, (response) => {
        console.log(response.statusCode);
        
        // 初始化变量存储所有数据块
        let rawData = [];

        // 分块接收数据,存入数组
        response.on("data", (chunk) => {
            rawData.push(chunk);
        });

        // 所有数据接收完成后处理
        response.on("end", () => {
            try {
                // 拼接所有Buffer块并解析为JSON
                const videoData = JSON.parse(Buffer.concat(rawData).toString());
                console.log(videoData);
                // 将数据返回给前端
                res.json(videoData);
            } catch (err) {
                // 捕获解析错误,避免应用崩溃
                console.error("JSON解析错误:", err.message);
                res.status(500).send("数据解析失败");
            }
        });

        // 监听请求错误
        response.on("error", (err) => {
            console.error("请求错误:", err.message);
            res.status(500).send("请求API失败");
        });
    });
});

app.listen("3000", () => {
    console.log("Running server on port 3000");
});

function validation(value) {
    const schema = Joi.object({
        userInput: Joi.string().min(2).required()
    });
    return schema.validate(value);
}

额外优化点

  • 对userInput做encodeURIComponent编码,避免特殊字符导致请求URL无效;
  • 若想简化代码,可使用axios等HTTP库,它会自动处理分块数据和JSON解析,无需手动拼接Buffer。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:50:40