NodeJS Express用sendFile指定contact.html却返回index.html如何解决
问题原因
Express 中间件和路由的执行顺序是按代码书写顺序从上到下匹配的,你把express.static静态中间件写在了自定义GET /contactForm路由的前面,而express.static默认开启了index配置,会自动匹配对应目录下的index.html作为路径根路由的默认返回值,所以你访问/contactForm时请求会先被静态中间件拦截,直接返回SE-Metro-Q目录下的index.html,根本不会执行后面的自定义路由。
解决方法
你可以根据自己的需求选择以下任意一种方案:
方案1:调整代码顺序(最常用,兼容多需求)
把自定义GET /contactForm路由放到express.static中间件的前面即可,这样访问/contactForm时会优先匹配自定义路由返回contact.html,其他/contactForm/xxx前缀的请求依然可以正常走静态中间件加载资源:
// 先写自定义路由 app.get('/contactForm', (req, res) => { res.sendFile('contact.html', { root: path.join(__dirname, '/../SE-Metro-Q') }); }) // 再写静态中间件 app.use("/contactForm", express.static(path.join(__dirname, '/../SE-Metro-Q')));
方案2:关闭静态中间件的默认index返回
如果你不需要静态中间件自动返回index.html的行为,可以给express.static加index: false配置:
app.use("/contactForm", express.static(path.join(__dirname, '/../SE-Metro-Q'), { index: false // 关闭默认index.html匹配 })); // 后面的自定义路由可以保持原有顺序 app.get('/contactForm', (req, res) => { res.sendFile('contact.html', { root: path.join(__dirname, '/../SE-Metro-Q') }); })
方案3:删除冗余的静态中间件(如果不需要挂载整个目录)
如果你除了contact.html之外,根本不需要对外暴露整个SE-Metro-Q目录的静态资源,直接删掉express.static那一行配置即可,只保留自定义路由就可以满足需求。
额外优化建议
可以给sendFile加错误捕获逻辑,避免文件不存在时服务端抛出异常:
app.get('/contactForm', (req, res) => { const contactPath = path.join(__dirname, '/../SE-Metro-Q/contact.html') res.sendFile(contactPath, (err) => { if (err) res.status(404).send('页面不存在') }) })
内容的提问来源于stack exchange,提问作者Nagusameta
相关产品推荐
相关产品推荐

