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

在Firebase可调用云函数中使用Puppeteer如何避免CORS错误

代码核心问题分析

  • 混用了Firebase两种云函数的语法:functions.https.onCall()是可调用云函数,专门对接Firebase客户端SDK,Firebase官方会自动处理CORS逻辑,不需要手动引入cors中间件。该接口的入参只有data和context,不存在req、res参数,你强行套cors(req, res, ...)的写法完全不符合可调用函数的规范,这是触发CORS报错的直接原因。
  • Puppeteer的执行逻辑没有正确返回Promise,云函数会在异步逻辑执行完成前提前销毁实例,就算CORS问题修复也无法正常完成截图。
  • 云函数是无图形界面的服务端环境,headless: false配置完全无法运行,需要改为无头模式,同时要补充Puppeteer在容器环境运行必须的启动参数,否则会启动失败。
  • 截图保存到example.png没有意义,云函数的本地磁盘是临时的,执行结束后文件就会被销毁,如果需要返回截图,应该转成base64或者上传到云存储。

修正后的可调用函数代码

const functions = require('firebase-functions');
const puppeteer = require('puppeteer');

exports.takePic = functions.https.onCall(async (data, context) => {
  // 可调用函数不需要手动加CORS中间件,Firebase自动处理
  const url = data.url;
  if (!url) {
    throw new functions.https.HttpsError('invalid-argument', '缺少url参数');
  }

  let browser;
  try {
    browser = await puppeteer.launch({
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-web-security',
        '--disable-features=IsolateOrigins',
        '--disable-site-isolation-trials'
      ],
      headless: 'new',
    });
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });
    // 截图转base64返回给前端,不要存在本地临时磁盘
    const screenshotBase64 = await page.screenshot({ encoding: 'base64' });
    await browser.close();
    // 正常返回结果,可调用函数会自动处理响应头避免CORS
    return {
      success: true,
      image: `data:image/png;base64,${screenshotBase64}`
    };
  } catch (err) {
    if (browser) await browser.close();
    throw new functions.https.HttpsError('internal', '截图执行失败', err.message);
  }
});

额外注意事项

  • 如果你是用普通HTTP请求(不是Firebase客户端SDK)调用这个接口,应该把onCall改成onRequest,再用你原来的cors中间件写法,两种函数的调用规范完全不同不要混用。
  • Puppeteer依赖体积较大,部署时要注意云函数的内存配置,建议至少配置1GB内存避免实例崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:00:05