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

Node.js Express中app.post内调用res.sendFile无响应(状态码200)

问题分析与解决方案

核心问题

你的代码存在四个关键问题导致res.sendFile无响应:

  1. 全局变量user_name引发并发冲突:多个用户同时提交时,全局变量会被覆盖,导致名称重复判断逻辑失效。
  2. readFileSync错误用法:同步读取文件时传入了回调函数,且未捕获读取/JSON解析异常,一旦出错会直接终止代码执行,无法返回响应。
  3. res.sendFile未处理错误:若文件路径错误或文件不存在,res.sendFile不会主动返回错误响应,客户端会一直等待。
  4. 正常提交分支无响应返回:名称不重复时,路由未向客户端返回任何响应,导致请求挂起。

修复步骤

1. 替换全局变量为Session存储

全局变量无法区分不同用户,改用express-session存储用户信息:

  • 安装依赖:npm install express-session
  • 配置Session中间件:
import session from 'express-session';

// 配置session,生产环境需调整secret和cookie参数
app.use(session({
    secret: 'your-custom-secret-key', // 替换为你的密钥
    resave: false,
    saveUninitialized: true,
    cookie: { secure: false } // 本地开发用false,生产环境HTTPS下改为true
}));
  • 修改POST /name路由:
app.post("/name", (req, res) => {
    req.session.user_name = req.body.name; // 存入session
    console.log("name: ", req.body.name);
    res.sendFile(__dirname + "/public/play.html");
});

2. 修复readFileSync用法

同步读取文件无需回调,且需捕获异常避免服务器崩溃:

// 替换原读取文件代码
let data;
try {
    data = readFileSync("./data/scores.json", 'utf8'); // 指定编码为utf8
} catch (error) {
    console.log(error);
    return res.status(500).send('读取分数文件失败');
}

3. 给res.sendFile添加错误处理

确保文件不存在时返回错误响应:

if (names.includes(user_name)) {
    console.log("Name used already!");
    res.sendFile(__dirname + "/public/dup_name.html", (err) => {
        if (err) {
            console.error('返回重复名称页面失败:', err);
            res.status(err.status || 500).send('页面加载失败');
        }
    });
    return;
};

4. 正常提交分支添加响应返回

名称不重复时,文件写入完成后向客户端返回响应:

writeFile("./data/scores.json", JSON.stringify(scores_data), (error) => {
    if (error) {
        console.log("保存分数失败: ", error);
        return res.status(500).send('保存分数失败');
    }
    console.log("Data written successfully to the file");
    res.sendFile(__dirname + "/public/success.html"); // 替换为你的成功页面,或返回文本
});

修改后的完整/publish-score路由代码

app.post("/publish-score", (req, res) => {
    const user_name = req.session.user_name; // 从session获取用户名
    const user_score = req.body.score;

    console.log("request name: ", user_name);
    console.log("request score: ", user_score);

    // 读取分数文件
    let data;
    try {
        data = readFileSync("./data/scores.json", 'utf8');
    } catch (error) {
        console.log(error);
        return res.status(500).send('读取分数文件失败');
    }
        
    // 检查名称是否重复
    let scores_data;
    try {
        scores_data = JSON.parse(data);
    } catch (parseError) {
        console.error('解析JSON失败:', parseError);
        return res.status(500).send('分数文件格式错误');
    }

    const names = scores_data.daily_puzzle.scores.map(entry => entry.name);
    console.log("names: ", names);
    
    if (names.includes(user_name)) {
        console.log("Name used already!");
        res.sendFile(__dirname + "/public/dup_name.html", (err) => {
            if (err) {
                console.error('返回重复名称页面失败:', err);
                res.status(err.status || 500).send('页面加载失败');
            }
        });
        return;
    };

    // 处理空值
    const push_name = user_name ?? "NoName"; 
    const push_score = user_score ?? "NoScore"; 

    scores_data.daily_puzzle.scores.push({
        "name": push_name,
        "score": push_score
    });

    // 写入文件并返回响应
    writeFile("./data/scores.json", JSON.stringify(scores_data), (error) => {
        if (error) {
            console.log("保存分数失败: ", error);
            return res.status(500).send('保存分数失败');
        }
        console.log("Data written successfully to the file");
        res.sendFile(__dirname + "/public/success.html"); // 替换为实际成功页面路径
    });  
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:34:57