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
相关产品推荐
相关产品推荐

