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

Node.js使用Handlebars提交登录请求后CSS、JS及图片等静态资源加载失效问题

问题描述

我在使用Node.js结合Handlebars开发登录功能时,提交登录请求后页面的CSS、JS及图片资源均无法正常加载,相关信息如下:

代码片段

exports.afterLogin = async (req, res) => {
try {
    const { email, password } = req.body;

    db.query('Select * FROM patient_login WHERE email= ?', [email], async (error, results) => {
        if(error){
            console.log(error);
        }
        console.log(results);
        if (!results || !(await bcrypt.compare(password, results[0].password))) {
            res.status(400).render('patientLogin', {
                message: 'Email or password is incorrect!',
                messageClass:'alert-warning'
            });
        }

页面截图

  • 输入登录凭证前页面:输入登录凭证前的页面截图
  • 输入错误凭证后页面:输入错误凭证后的页面截图

控制台报错信息

POST http://127.0.0.1:3050/auth/afterLogin 400 (Bad Request)
Refused to apply style from 'http://127.0.0.1:3050/auth/css/index.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
GET http://127.0.0.1:3050/auth/images/logo.png 404 (Not Found)
GET http://127.0.0.1:3050/auth/javascript/validateLogin.js net::ERR_ABORTED 404 (Not Found)

路径说明

  • 初始访问页面路径:/home/patientLogin
  • 输入错误凭证后地址栏路径变为:/home/auth/afterlogin

根因分析
  • 静态资源使用相对路径引用:模板中CSS、JS、图片用的是css/index.css这类相对路径,浏览器会基于当前页面URL拼接资源地址。登录报错后页面URL多了/auth层级,拼接出来的资源地址/auth/css/index.css不存在,服务端返回404错误页(HTML格式),触发MIME类型不匹配报错。
  • 登录错误时直接渲染页面未重定向:校验失败后直接用res.render()返回登录页内容,浏览器地址栏停留在POST请求的/auth/afterLogin路径,没有回到登录页原始路径,导致路径层级异常。
解决步骤
  1. 修改模板静态资源为绝对路径
    所有静态资源引用前加/,浏览器会直接从站点根目录查找资源,不受当前页面路径影响,示例修改如下:
<!-- 改前 -->
<link rel="stylesheet" href="css/index.css">
<script src="javascript/validateLogin.js"></script>
<img src="images/logo.png">
<!-- 改后 -->
<link rel="stylesheet" href="/css/index.css">
<script src="/javascript/validateLogin.js"></script>
<img src="/images/logo.png">
  1. 修改登录错误逻辑为重定向
    校验失败后重定向回原始登录页,通过查询参数传递提示信息,既可以修复路径问题,还能避免用户刷新页面重复提交表单,代码修改如下:
// afterLogin接口中错误返回逻辑修改
if (!results || !(await bcrypt.compare(password, results[0].password))) {
    const msg = encodeURIComponent('Email or password is incorrect!')
    res.redirect(`/home/patientLogin?message=${msg}&messageClass=alert-warning`);
}

在登录页路由中读取参数传递给模板:

app.get('/home/patientLogin', (req, res) => {
    res.render('patientLogin', {
        message: req.query.message || '',
        messageClass: req.query.messageClass || ''
    });
})
  1. 确认静态资源配置正常
    检查Express静态资源中间件配置,确保静态资源目录映射正确,示例配置(静态资源放在项目根目录public文件夹下):
app.use(express.static('public'))

如果配置了静态资源访问前缀,比如app.use('/static', express.static('public')),则需要把资源路径对应修改为/static/css/index.css。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 17:36:06