event.preventDefault()影响执行,Express无法跳转至result.ejs求助
问题分析与解决方案
当前问题
点击提交按钮后,loading.ejs能正常加载,但Python脚本执行完成后,result.ejs始终无法渲染。核心原因是前端逻辑存在冲突:
- 执行
window.location.href = "/loading"后,浏览器已经跳转到新页面,原页面发起的fetch("/submit")请求的响应(res.redirect("/result"))无法作用到当前浏览器上下文,导致跳转失效。 event.preventDefault()阻止了表单的默认提交行为,但后续的异步请求无法联动浏览器页面跳转。
方案:由Express主导全流程
通过**会话(Session)**跟踪任务状态,结合前端轮询实现“立即显示loading → 后台处理任务 → 完成后跳转result”的逻辑,完全由Express控制任务生命周期。
1. 配置Express会话
首先安装依赖:
npm install express-session
在Express入口文件中添加Session配置:
const session = require('express-session'); app.use(session({ secret: 'your-custom-secret-key', // 替换为自定义密钥 resave: false, saveUninitialized: true, cookie: { secure: false } // 生产环境建议开启HTTPS并设为true }));
2. 修改/submit路由逻辑
先渲染loading页面,再后台执行Python脚本,完成后更新会话状态:
const { spawn } = require('child_process'); const path = require('path'); app.post("/submit", (req, res) => { const form_link = req.body.form_link; // 初始化会话中的任务状态 req.session.taskCompleted = false; // 立即返回loading页面 res.render("loading.ejs"); // 后台启动Python脚本 const pythonProcess = spawn("python", [path.join(__dirname, "./py_scripts/script.py"), form_link]); // 脚本执行完成后更新状态 pythonProcess.on("exit", (code) => { console.log(`Python脚本执行完成,退出码:${code}`); req.session.taskCompleted = true; req.session.save(); // 强制保存会话更新 }); // 捕获脚本启动错误(可选) pythonProcess.on("error", (err) => { console.error("Python脚本启动失败:", err); req.session.taskCompleted = true; req.session.save(); }); });
3. 添加任务状态查询路由
供loading页面轮询任务进度:
app.get("/check-task-status", (req, res) => { res.json({ completed: req.session.taskCompleted || false }); });
4. 改造loading.ejs
添加轮询逻辑,任务完成后自动跳转:
<!DOCTYPE html> <html> <head> <title>处理中</title> </head> <body> <h1>正在处理,请稍候...</h1> <script> // 每隔1秒查询一次任务状态 const statusChecker = setInterval(async () => { const response = await fetch("/check-task-status"); const data = await response.json(); if (data.completed) { clearInterval(statusChecker); window.location.href = "/result"; } }, 1000); </script> </body> </html>
5. 简化index.ejs
移除原有的异步脚本,让表单直接提交到/submit路由:
<!DOCTYPE html> <html> <head> <title>首页</title> </head> <body> <form class="form" action="/submit" method="POST"> <input type="text" name="form_link" placeholder="输入目标链接" required> <button class="form-button" type="submit">提交</button> </form> </body> </html>
核心逻辑说明
- 会话(Session)用于在服务器端存储任务状态,避免前端状态丢失。
- loading页面通过轮询主动获取任务状态,确保任务完成后能及时跳转。
- Express完全控制任务的启动、状态更新流程,前端仅负责页面展示与状态查询。
内容的提问来源于stack exchange,提问作者Anamay Narkar
相关产品推荐
相关产品推荐

