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

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(可使用cors npm包),否则fetch请求会被浏览器拦截。

内容的提问来源于stack exchange,提问作者Bryant

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:34:57