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

NextJS 13 API路由如何正确返回Puppeteer生成的截图?

NextJS 13 API返回Puppeteer截图二进制文件解决方案

我基于NextJS 13构建了一个API,通过URL参数调用Puppeteer生成网页截图,但运行后遇到以下错误:

错误:对象不能作为React子元素(找到:键为{}的对象)。如果您想渲染子元素集合,请改用数组。

已经通过console.log确认截图数据生成成功,但无法返回文件类型的响应,需要解决如何通过该API提供二进制文件。

原代码

import puppeteer from 'puppeteer';
import { NextResponse } from 'next/server';

export default async function GET(req, res) {
    const url = req.searchParams.url;

    if (!url) {
        return res.status(400).json({ error: "URL parameter is required" });
    }

    try {
        const browser = await puppeteer.launch({
            headless: "new"
        });

        const page = await browser.newPage();
        await page.goto(url);

        const screenshot = await page.screenshot({
            encoding: 'base64',
        });

        await browser.close();
        return NextResponse.json(
            { status: 200 },
            { blob: `data:image/jpeg;base64,${screenshot}` },
        );

    } catch (error) {
        console.error(error);
        return NextResponse.json(
            { error: "Something went wrong" },
            { status: 500 }
        );
    }
}

问题分析

原代码错误地使用NextResponse.json()传递二进制数据,NextResponse.json()仅用于返回JSON格式响应,这种用法不符合API规范,导致返回内容被客户端当作React子元素处理,从而抛出错误。此外,将截图转成base64再返回会增加额外的编码开销,不如直接返回二进制Buffer高效。

修正后的代码

import puppeteer from 'puppeteer';
import { NextResponse } from 'next/server';

export async function GET(req) {
    // NextJS 13 App Router中正确获取查询参数的方式
    const url = req.nextUrl.searchParams.get('url');

    if (!url) {
        return NextResponse.json(
            { error: "URL parameter is required" },
            { status: 400 }
        );
    }

    try {
        const browser = await puppeteer.launch({
            headless: "new"
        });

        const page = await browser.newPage();
        await page.goto(url);

        // 直接获取二进制Buffer,无需转base64
        const screenshotBuffer = await page.screenshot({
            encoding: 'binary',
        });

        await browser.close();

        // 返回二进制响应,设置正确的响应头
        return new Response(screenshotBuffer, {
            headers: {
                'Content-Type': 'image/jpeg',
                'Content-Disposition': 'inline; filename="screenshot.jpg"'
            },
            status: 200
        });

    } catch (error) {
        console.error(error);
        return NextResponse.json(
            { error: "Something went wrong" },
            { status: 500 }
        );
    }
}

关键调整点

  1. 查询参数获取:NextJS 13 App Router中,API路由的GET函数需通过req.nextUrl.searchParams.get('url')获取查询参数,替代原代码的req.searchParams.url。
  2. 二进制数据处理:直接获取截图的二进制Buffer,避免base64编码的额外开销。
  3. 响应方式:使用原生Response对象返回二进制数据,设置Content-Type为image/jpeg让客户端识别为图片,Content-Disposition头控制图片是直接显示还是下载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:50:02