Express搭配Pug模板引擎时res.redirect()重定向失效问题
问题根因
跳转失效和Pug模板引擎没有关系,核心问题出在前后端请求交互逻辑:
你在前端用fetch发送异步请求时,已经通过e.preventDefault()阻止了表单的默认同步提交行为,此时服务端返回的302 Redirect响应只会被fetch内核自动处理,不会触发浏览器顶层页面的跳转——异步请求的响应不会直接驱动浏览器页面导航,没有额外JS逻辑处理的话,页面自然会停在登录页。
修复方案
两种实现方式按需选择即可:
方案1:保留fetch异步提交逻辑,前端手动触发跳转
在fetch的响应回调中,判断登录校验通过后,手动执行页面导航:
// login.js 核心代码示例 const form = document.querySelector('form') form.addEventListener('submit', async (e) => { e.preventDefault() const email = form.querySelector('input[name="email"]').value const password = form.querySelector('input[name="password"]').value const res = await fetch('/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }) if (res.ok) { // 登录成功手动跳转到仪表盘,用replace不会在浏览历史留存登录页记录 window.location.replace('/dashboard') return } // 此处写登录失败的提示逻辑,比如展示账号密码错误文案 })
优化提示:用这个方案的话,服务端登录接口不需要写res.redirect(),校验通过后直接返回200状态码的成功响应即可,多余的302响应只会增加不必要的请求开销。
方案2:移除异步提交逻辑,走表单原生同步提交
如果不需要无刷新登录体验,可以删掉login.js里的提交监听、fetch请求相关代码,给登录表单标签配置action="/login"、method="POST"属性,原生表单提交会自动跟随服务端的res.redirect()响应完成跳转,不需要额外写前端跳转代码。
注意:原生表单默认提交的参数格式是
application/x-www-form-urlencoded,无法被express.json()中间件解析,需要在Express入口里补充配置app.use(express.urlencoded({ extended: true }))才能正常拿到表单提交的账号密码参数。
内容的提问来源于stack exchange,提问作者Karan Rajput
相关产品推荐
相关产品推荐

