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

使用Express搭建静态HTML页面遇报错:Cannot GET /war及__dirname未定义

解决Express静态页面部署的两个问题:__dirname未定义与路由无法访问

问题分析

你遇到两个核心问题:

  • 控制台报错ReferenceError: __dirname is not defined:因为你使用了ES模块(import语法),而__dirname是CommonJS模块专属变量,ES模块默认不提供这个变量。
  • 页面显示Cannot GET /war:你定义了路由规则但没把Router挂载到Express应用上,导致路由完全不生效。

另外代码里还有几个细节问题会影响功能,一起修复:

分步修复

1. 替代__dirname(解决ES模块路径问题)

在ES模块中,用import.meta.url获取当前模块的文件URL,再通过path模块转换为等效的__dirname:

import express from 'express';
const app = express();
const router = express.Router();
import path from 'path';
import { fileURLToPath } from 'url'; // 新增导入
import {getData, createData} from './server.js' // 确保导入createData函数

// 定义ES模块下的__dirname替代变量
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

2. 挂载路由(解决Cannot GET /war)

定义完Router规则后,必须把它挂载到app实例上,否则路由不会生效:

// 在HTML Routes定义完成后添加这行
app.use(router);

3. 修复其他功能问题

  • 解析POST请求体:POST接口需要解析JSON格式的请求数据,添加中间件:
    // 放在路由定义之前
    app.use(express.json());
    
  • 端口号不一致:listen用的7171,但日志输出写的9191,统一成同一个端口:
    app.listen(7171, ()=> {
        console.log('Server is running on port 7171')
    })
    
  • 简化服务启动逻辑:sendStats函数不需要async包裹,路由定义直接放在顶层即可,避免重复注册问题;同时不需要await调用启动函数,直接启动服务:
    // 把数据路由从函数里移出来,直接定义
    app.get("/data", (req,res)=> {
        const data = getData()
        res.json(data)
    })
    app.post("/data",(req, res) => {
        const {name, score} = req.body
        const data = createData(name, score)
        res.json(data)
    })
    

完整修复后的代码示例

import express from 'express';
const app = express();
const router = express.Router();
import path from 'path';
import { fileURLToPath } from 'url';
import {getData, createData} from './server.js'

// ES模块下替代__dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 解析JSON请求体
app.use(express.json());

// HTML路由规则
router.get('/', (req,res)=> {
    res.sendFile(path.join(__dirname, "../start.html"));
})
router.get('/war', (req,res)=> {
    res.sendFile(path.join(__dirname, "../index.html"));
})
router.get('/score', (req,res)=> {
    res.sendFile(path.join(__dirname, "../finalScore.html"));
})

// 挂载路由到应用
app.use(router);

// 数据接口路由
app.get("/data", (req,res)=> {
    const data = getData()
    res.json(data)
})
app.post("/data",(req, res) => {
    const {name, score} = req.body
    const data = createData(name, score)
    res.json(data)
})

// 全局错误处理
app.use((err, req, res, next) => {
    console.log(err.stack)
    res.status(500).send('Something Broke!')
})

// 启动服务
app.listen(7171, ()=> {
    console.log('Server is running on port 7171')
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:15:18