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

Node.js Express应用无法加载CSS静态文件问题求助

问题核心原因

CSS加载失败、访问CSS地址显示纯文本,是静态资源配置与前端引用路径不匹配+动态路由拦截静态资源请求共同导致的,和CORS、浏览器缓存无关:

  • 你配置app.use(express.static(path.join(__dirname, '/public')));的作用是将public文件夹设为静态资源根目录,访问该目录下的文件不需要加/public前缀,直接写根路径+文件名即可。但你在ejs里写的CSS引用路径是/public/styles.css,路径完全错误。
  • 你额外配置的app.use("/styles", express.static(__dirname + '/styles'));是无效配置,你的项目根目录下根本不存在styles文件夹,CSS实际存放在public目录下。
  • 你把views模板文件夹设为了静态资源目录,存在源码泄露风险,且完全没必要。
  • 产品路由中router.get('/:book', product_controller.product_details);是一级泛匹配动态路由,你写错路径的CSS请求/public/styles.css不会走到静态资源处理逻辑,会被这个路由直接拦截,返回产品接口的内容,所以你访问CSS地址看到的是纯文本,不是合法的CSS文件,浏览器自然无法加载样式。
  • index.ejs里的<base href="/">写在了CSS引用标签之后,不会对前面的资源引用生效;同时你引用的根路径app.js不存在于静态资源目录,后续也会报404错误。
修复步骤
  1. 清理app.js中无效的静态资源配置
    只保留public目录作为唯一静态资源入口,删掉无效的views、styles目录挂载配置,注意静态资源配置必须放在业务路由挂载代码之前,避免请求被路由优先拦截。修正后的app.js核心配置:
const express = require('express');
const bodyParser = require('body-parser');
const product = require('./routes/product.routes');
const app = express();
const path = require('path');
const cors = require('cors');

app.set('views', __dirname + '/views');
app.set('view engine', 'ejs')

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cors({ origin: '*' }));
// 只保留这一行静态资源配置即可
app.use(express.static(path.join(__dirname, 'public')));
// 删掉以下两行无效配置
// app.use(express.static(path.join(__dirname, 'views')));
// app.use("/styles", express.static(__dirname + '/styles'));
app.use('/product', product);

let port = 3000;
app.listen(port, () => {
    console.log('Server is up and running on port number ' + port);
});
  1. 修正index.ejs中的资源引用
  • 把<base href="/">移到head标签最开头,保证所有资源引用都基于根路径
  • 将CSS引用路径改为/styles.css,不需要带public前缀
  • 删掉不存在的根路径app.js引用,后续如果要加前端js,放到public目录下再按根路径引用即可
    修正后的index.ejs代码:
<html lang="en">
  <head>
    <base href="/"> 
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <link rel="stylesheet" type="text/css" href='/styles.css'/>
  </head>
  <body>
    <h1>BookBooker</h1>
      <h2>A library app for personal use.</h2>
      <form action="/create" method="POST">
        <input type="text" placeholder="Writer" name="name" />
        <input type="text" placeholder="Book" name="book" />
        <button type="submit">Submit</button>
      </form>
  </body>
</html>
  1. 验证效果
    修改完成后重启Node服务,直接访问http://localhost:3000/styles.css会返回正确的CSS文件,响应头Content-Type自动为text/css,打开页面即可看到正常加载的样式。
额外注意事项
  • express.static挂载的静态资源目录,对外访问时不需要写目录本身的名字,比如public/styles.css访问路径就是/styles.css,如果后续在public下新建css子文件夹存放public/css/styles.css,访问路径直接写/css/styles.css即可,不需要修改服务端配置。
  • 不要把存放模板的views目录设为静态资源目录,否则用户可以直接下载你的ejs模板源码,存在安全风险。
  • 带通配符/动态参数的路由尽量不要放在一级路径,避免拦截静态资源或其他正常接口请求,可以给这类接口加统一前缀,比如把产品详情接口改成/product/detail/:book,就不会误拦截根路径下的静态资源请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:01:07