Vue登录验证通过后,Node.js后端无法触发页面跳转的问题
登录后后端
res.redirect不触发Vue页面跳转的问题解决 我正在学习JavaScript、Vue和Node.js,登录功能遇到问题:前端Vue登录表单通过fetch请求提交数据,后端Node.js接口能接收并匹配密码成功,执行了res.redirect(301, '/home'),但前端页面完全没跳转。相关代码如下:
前端Vue表单及脚本
<form> <div class="mb-3"> <label for="usernameEmailMobile">Username/Email/Mobile</label> <input type="text" class="form-control" id="usernameEmailMobile" placeholder="Enter username, email, or mobile number" required v-model="stateLogin.newInput" > </div> <div class="mb-3"> <label for="password">Password</label> <input type="password" class="form-control" id="password" placeholder="Enter password" required v-model="stateLogin.passwordInput"> </div> <button @click="login()" type="submit" class="btn btn-success ">Login</button> </form> <script> import loginCRUD from '../modules/loginCRUD.js' export default { name:"loginView", setup(){ const {stateLogin, login} = loginCRUD() return {stateLogin, login} } } </script>
登录模块代码
import {reactive} from 'vue' const doLogin =() =>{ const stateLogin = reactive({ newInput: '', passwordInput: '' }) const login = () =>{ const request = { method : "POST", headers: { "Content-Type" : "application/json" //authtoken bisa disini }, body: JSON.stringify({ input: stateLogin.newInput , password: stateLogin.passwordInput , }) } fetch("http://localhost:3000/user/login", request) } return { stateLogin, login } } export default doLogin
Node.js后端代码
router.post('/login', async (req,res) =>{ const tempUser = req.body.input; const password = req.body.password; // const user = await User.findOne({ // $or: // [ // {username : tempUser}, // {mobilePhone : tempUser}, // {email : tempUser} // ] // }) const user = await User.findOne({username : tempUser }) const worker = await Worker.findOne({username : tempUser }) if(user != null){ if(password == user.password){ return res.redirect(301,`/home`) }else{ } }else{ } //const match = await bcrypt.cmopare(req.body.password, user.password) })
问题原因
- 前端通过fetch发起的AJAX请求不会自动处理后端的redirect响应。浏览器只有在直接发起的页面级请求(如地址栏输入、a标签跳转、表单默认提交)中,才会执行跳转。
- 表单未阻止默认提交行为,点击按钮时会同时触发fetch请求和表单默认提交(导致页面刷新,逻辑混乱)。
解决方案
1. 阻止表单默认提交行为
给form标签添加@submit.prevent,避免默认提交干扰:
<form @submit.prevent> <!-- 原有表单内容不变 --> <button @click="login()" type="submit" class="btn btn-success">Login</button> </form>
2. 后端返回JSON响应,由前端控制跳转
后端不再使用res.redirect,而是返回包含状态和跳转路径的JSON数据:
router.post('/login', async (req,res) =>{ const tempUser = req.body.input; const password = req.body.password; const user = await User.findOne({username : tempUser }) const worker = await Worker.findOne({username : tempUser }) if(user != null){ // 建议启用bcrypt验证密码,不要明文对比 // const match = await bcrypt.compare(password, user.password) // if(match) { ... } if(password == user.password){ return res.status(200).json({ success: true, redirectTo: '/home' }) }else{ return res.status(401).json({success: false, message: '密码错误'}) } }else{ return res.status(404).json({success: false, message: '用户不存在'}) } })
3. 前端接收响应后用Vue Router跳转
修改登录模块,引入Vue Router并在登录成功后执行跳转:
import {reactive} from 'vue' import { useRouter } from 'vue-router' const doLogin =() =>{ const router = useRouter() const stateLogin = reactive({ newInput: '', passwordInput: '' }) const login = async () =>{ try { const request = { method : "POST", headers: { "Content-Type" : "application/json" }, body: JSON.stringify({ input: stateLogin.newInput , password: stateLogin.passwordInput , }) } const response = await fetch("http://localhost:3000/user/login", request) const data = await response.json() if(data.success){ // 通过Vue Router跳转到首页 router.push(data.redirectTo) }else{ // 提示用户错误信息 alert(data.message) } } catch (error) { console.error('登录请求失败:', error) alert('网络错误,请稍后重试') } } return { stateLogin, login } } export default doLogin
额外提醒
- 务必启用bcrypt加密密码,不要明文存储或对比密码(代码中已注释相关逻辑,记得启用)。
- 如果前后端端口不同,需在Node.js后端配置CORS(可使用
corsnpm包),否则fetch请求会被浏览器拦截。
内容的提问来源于stack exchange,提问作者Bryant
相关产品推荐
相关产品推荐

