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

Node.js+Express项目如何向EJS传函数避免其立即自动执行?

问题根源

你混淆了服务端运行逻辑和客户端运行逻辑:

  • Puppeteer是Node.js生态工具,只能运行在你的Express服务端,不能直接传递到用户浏览器端执行
  • EJS是服务端模板引擎,你把startBrowser传给res.render的时候,服务端渲染页面的过程中就会直接执行这个函数,所以才会页面还没到用户浏览器就自动打开了浏览器窗口
  • 前端页面的onclick只能调用浏览器环境下的前端JS函数,根本无法访问服务端的Node.js函数

修复步骤

1. 修正browserModule.js的基础错误

const puppeteer = require('puppeteer');
// 修正导出写法和函数定义的括号
module.exports = async function startBrowser() {
  let browser;
  try {
    console.log("Opening the browser......");
    browser = await puppeteer.launch({
        headless: false,
        args: [
          "--disable-setuid-sandbox",
        ],
        'ignoreHTTPSErrors': true
    });
    return { success: true }
  } catch (err) {
    console.log("Could not create a browser instance => : ", err);
    return { success: false, msg: err.message }
  }
}

2. 新增服务端接口用于触发浏览器启动

在你的Express路由文件中新增一个接口,专门处理启动浏览器的请求:

const browserModule = require('../browserModule');
// 原有渲染页面的路由保留
router.get('/new', pageController.renderNewForm);
// 新增触发启动浏览器的接口
router.get('/api/start-browser', async (req, res) => {
  const result = await browserModule();
  res.json(result);
});

3. 修正pageController的渲染逻辑

不要把服务端函数传给模板,直接正常渲染页面即可:

module.exports.renderNewForm = async (req, res) => {
  // 不需要传startBrowser函数,直接渲染页面
  res.render('new');
}

4. 修改EJS页面的点击逻辑

按钮点击时通过前端AJAX请求调用服务端的启动接口:

<button class="btn btn-info" onclick="openBrowser()">Open Book Site</button>
<script>
async function openBrowser() {
  const res = await fetch('/api/start-browser');
  const data = await res.json();
  if(data.success) {
    alert('浏览器启动成功');
  } else {
    alert('启动失败:' + data.msg);
  }
}
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:18:00