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

Node.js使用Express框架无法隐藏URL中文件扩展名问题求助

问题原因

你的代码存在3个核心错误,导致运行不符合预期:

  • 中间件优先级错误:express.static 静态资源中间件定义在自定义路由之前,优先级更高,请求会先匹配静态资源。只有无对应静态文件时才会进入自定义路由,同时也会直接暴露带.json后缀的文件访问路径。
  • 文件路径拼接错误:自定义路由中直接使用name+'.json'作为路径,没有拼接data目录路径,fs.open默认从项目根目录查找文件,自然找不到data目录下的users.json,返回404。
  • 文件读取逻辑错误:fs.open拿到的是文件描述符(数字类型),直接调用res.json(fd)只会返回数字,不会返回JSON文件内容;同时你没有通过fs调用close方法,会直接报错。

修复方案

步骤1:调整中间件顺序/移除不必要的静态中间件

如果你不需要对外直接暴露带.json后缀的访问路径,可以直接删除app.use('/api', express.static(...))这行代码;如果需要保留,就把它放到自定义路由的后面。

步骤2:修正文件路径与读取逻辑

直接使用express内置的res.sendFile方法简化逻辑,同时增加路径安全校验,避免路径穿越漏洞。

修复后完整代码

const express = require('express');
const path = require('path');
const fs = require('fs');

const app = express();
const PORT = 3000;

// 可选:如果不需要暴露带后缀的访问,可删除下面这行静态中间件配置
// app.use('/api', express.static(path.join(__dirname,'data')) );

app.get('/api/:name',(req,res) => {
    let {name} = req.params;
    // 拼接正确的文件路径
    const filePath = path.join(__dirname, 'data', `${name}.json`);
    // 校验文件是否在data目录内,防止路径穿越攻击
    if (!filePath.startsWith(path.join(__dirname, 'data'))) {
        return res.status(403).end('非法访问');
    }
    // 直接发送文件,express会自动处理文件存在性校验、响应头设置
    res.sendFile(filePath, (err) => {
        if (err) {
            if (err.code === 'ENOENT') {
                return res.status(404).end(`404 ${name}.json不存在`);
            }
            res.status(500).end('服务器错误');
        }
    });
});

// 如果保留了静态中间件,要放在路由定义之后
// app.use('/api', express.static(path.join(__dirname,'data')) );

app.listen(PORT, () => {
    console.log(`服务运行在 http://localhost:${PORT}`);
});

修改后访问localhost:3000/api/users即可正常返回users.json的内容,同时默认禁止带.json后缀的访问,如果需要保留带后缀的访问,放开对应静态中间件的注释即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:27:03