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

仅当POST请求返回403时阻止React Link跳转的问题排查

问题描述

我要实现的逻辑是:当创建房间的POST请求返回403 Forbidden(房间名已存在于Lobbies.json)时,阻止React的Link组件跳转;请求成功则正常跳转。但现在代码里的.then函数完全没执行(控制台看不到"Testing"输出),没法实现预期逻辑,求帮忙排查原因。


相关代码

Lobbies.json

{"Lobbies":[]}

jsonWorker.js

const fs = require('fs');

function lobbyUpdater(name, password) {
    let rawdata = fs.readFileSync('Lobbies.json');
    let data = JSON.parse(rawdata);
    // data.Lobbies.length = 0; // Remove this for production
    let newLobby = {"Name":name, "Password":password, "Players":1, "Mode":"", "Word":""}
    data.Lobbies.push(newLobby)
    fs.writeFile('Lobbies.json', JSON.stringify(data), 'utf8', function(err) {
        if (err) throw err;
    });
}

function lobbyAvailable(name) {
    let rawdata = fs.readFileSync('Lobbies.json');
    let data = JSON.parse(rawdata);
    for (let i = 0; i < data.Lobbies.length; i++) {
        if (data.Lobbies[i].Name.toUpperCase() === name.toUpperCase()) {
            return false;
        }
    }
    return true;
}


module.exports = {
    lobbyUpdater,
    lobbyAvailable
};

后端index.js中的POST请求处理

app.post('/newLobby', (req, res) => {
  console.log("Lobby Name:", req.body.lobbyName);
  console.log("Lobby Password:", req.body.lobbyPassword);
  const jsonWorker = require('./jsonWorker');
  if (jsonWorker.lobbyAvailable(req.body.lobbyName)) {
    jsonWorker.lobbyUpdater(req.body.lobbyName, req.body.lobbyPassword);
  }
  else {
    res.sendStatus(403);
    console.log("Stopped A Lobby From Being Created");
  }
});

React组件代码

<Link id="testLink" to="/Waiting-For-Players"><button id="submit" onClick={sendingRequest} className="WaitingForPlayers">Create Lobby</button></Link>

sendingRequest函数

function sendingRequest(event) {
  event.preventDefault();
  $.post("http://localhost:4000/newLobby",
    {
        lobbyName: document.getElementById('lobbyName').value,
        lobbyPassword: document.getElementById('lobbyPassword').value
    },
    function (data, status) {
      console.log("Data", data);
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
      console.log("Error received:", errorThrown);
      console.log("Stopping the post request.");
      return;
    })
    .then(function() {
      // Follow the Link component
      let linkToUse = document.getElementById("testLink");
      window.location.assign(linkToUse.to);
      console.log("Testing")
    });
}

问题排查与修复

1. 后端未返回成功响应

当前后端代码里,房间创建成功时没有给前端返回任何响应(没调用res.send/res.sendStatus),导致前端AJAX请求一直处于等待状态,.then自然不会触发。

修复后端代码:

app.post('/newLobby', (req, res) => {
  console.log("Lobby Name:", req.body.lobbyName);
  console.log("Lobby Password:", req.body.lobbyPassword);
  const jsonWorker = require('./jsonWorker');
  if (jsonWorker.lobbyAvailable(req.body.lobbyName)) {
    jsonWorker.lobbyUpdater(req.body.lobbyName, req.body.lobbyPassword);
    // 添加成功响应,告诉前端请求完成
    res.sendStatus(201); // 也可以用res.json({success: true})返回更多信息
  }
  else {
    res.sendStatus(403);
    console.log("Stopped A Lobby From Being Created");
  }
});

2. jQuery AJAX链式调用逻辑问题

原代码把跳转逻辑放在.then里,但.fail回调的return不会中断链式调用,而且.then不管成功失败都会执行。应该把跳转逻辑放到.done(仅成功时触发)里,失败时不做处理即可:

修改sendingRequest函数:

function sendingRequest(event) {
  event.preventDefault();
  $.post("http://localhost:4000/newLobby",
    {
        lobbyName: document.getElementById('lobbyName').value,
        lobbyPassword: document.getElementById('lobbyPassword').value
    })
    .done(function(data, status) {
      console.log("Data", data);
      // 仅请求成功时跳转
      let linkToUse = document.getElementById("testLink");
      // 注意:React Link的to是组件属性,不是DOM元素属性,直接拿会出错,建议直接写路径
      window.location.assign('/Waiting-For-Players');
      console.log("Testing");
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
      console.log("Error received:", errorThrown);
      console.log("房间名已存在,无法创建");
      // 失败时不执行跳转逻辑
    });
}

3. React Router跳转方式优化

原代码用window.location.assign跳转违背了React单页应用的逻辑,更推荐用React Router的钩子来处理:

以React Router v6为例:

import { useNavigate } from 'react-router-dom';

function YourComponent() {
  const navigate = useNavigate();

  function sendingRequest(event) {
    event.preventDefault();
    $.post("http://localhost:4000/newLobby",
      {
          lobbyName: document.getElementById('lobbyName').value,
          lobbyPassword: document.getElementById('lobbyPassword').value
      })
      .done(function() {
        // 成功后跳转
        navigate('/Waiting-For-Players');
        console.log("Testing");
      })
      .fail(function(jqXHR) {
        if (jqXHR.status === 403) {
          console.log("房间名已存在,无法创建");
        }
      });
  }

  // 这里不需要Link组件了,跳转逻辑完全由js控制
  return (
    <button id="submit" onClick={sendingRequest} className="WaitingForPlayers">Create Lobby</button>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:01:54