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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:27:02