如何在Node.js+Express中检测Puppeteer脚本执行完成并在HTML页展示状态
实现方案
后端代码调整
你现有代码的核心问题是/puppeteer路由没有等待Puppeteer脚本执行完成就结束了请求,也没有返回执行结果,同时goToSite函数缺少错误捕获和实例销毁逻辑。修改后的完整后端代码如下:
const express = require('express') const puppeteer = require('puppeteer'); const bodyParser = require('body-parser'); const app = express() const port = 1000 app.use(bodyParser.urlencoded({ extended: true })); // 新增JSON解析支持,方便返回标准化结果 app.use(express.json()) app.use(express.static('public')); const goToSite = async(url) => { let browser; try { browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 补充原有逻辑缺失的页面跳转逻辑 await page.goto(url); // 注:新版本Puppeteer已将waitFor方法废弃,替换为waitForTimeout await page.waitForTimeout(1000); await browser.close(); return { success: true, msg: 'Puppeteer脚本执行成功' } } catch (err) { // 执行失败时也要关闭浏览器实例,避免内存泄漏 if(browser) await browser.close(); return { success: false, msg: `执行失败:${err.message}` } } }; app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }) // 将路由修改为异步处理,等待脚本执行完成后返回结果 app.post('/puppeteer', async (req, res) => { const execResult = await goToSite(req.body.url); res.json(execResult); }) app.listen(port, () => { console.log(`服务已启动,访问地址:http://localhost:${port}`) })
前端页面实现
在项目根目录新建index.html文件,实现提交表单、状态提示的逻辑,代码如下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Puppeteer执行状态检测</title> <style> .status { margin-top: 20px; padding: 10px 15px; border-radius: 4px; } .success { background-color: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; } .error { background-color: #fef2f2; color: #991b1b; border: 1px solid #fecaca; } .loading { background-color: #fffbeb; color: #92400e; border: 1px solid #fed7aa; } button:disabled { opacity: 0.6; cursor: not-allowed; } </style> </head> <body> <div style="max-width: 600px; margin: 30px auto;"> <h3>Puppeteer脚本执行工具</h3> <div style="margin: 20px 0;"> <input type="text" id="urlInput" placeholder="请输入要访问的URL,例如:https://example.com" style="width: 400px; padding: 8px 12px; margin-right: 10px; border: 1px solid #e5e7eb; border-radius: 4px;" > <button id="submitBtn" style="padding: 8px 20px; background: #2563eb; color: #fff; border: none; border-radius: 4px; cursor: pointer;"> 执行脚本 </button> </div> <div id="statusBox" class="status" style="display: none;"></div> </div> <script> const submitBtn = document.getElementById('submitBtn'); const urlInput = document.getElementById('urlInput'); const statusBox = document.getElementById('statusBox'); submitBtn.addEventListener('click', async () => { const targetUrl = urlInput.value.trim(); if (!targetUrl) { alert('请先输入要访问的URL'); return; } // 展示加载状态 statusBox.style.display = 'block'; statusBox.className = 'status loading'; statusBox.textContent = '脚本正在执行,请稍候...'; submitBtn.disabled = true; try { const response = await fetch('/puppeteer', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `url=${encodeURIComponent(targetUrl)}` }); const result = await response.json(); // 根据执行结果更新页面状态 statusBox.className = result.success ? 'status success' : 'status error'; statusBox.textContent = result.msg; } catch (err) { statusBox.className = 'status error'; statusBox.textContent = `请求异常:${err.message}`; } finally { submitBtn.disabled = false; } }) </script> </body> </html>
关键改动说明
- 给
goToSite函数添加了完整的错误捕获逻辑,执行完成后无论成功失败都会关闭浏览器实例,避免内存泄漏,同时返回标准化的执行结果 - 将
/puppeteer路由修改为异步处理模式,等待Puppeteer脚本执行完成后再返回JSON格式的执行状态 - 前端采用异步提交请求的方式,提交后实时展示加载状态,拿到后端返回结果后自动更新页面提示信息
内容的提问来源于stack exchange,提问作者Vzupo
相关产品推荐
相关产品推荐

