使用Express.static时HTML资源路径需用绝对路径吗?
文件结构
项目根目录/ ├── public/ │ ├── index.html │ └── styles.css ├── codebase/ │ ├── library.js │ └── library.css ├── app.js └── server.js
代码文件
/public/index.html
<!DOCTYPE html> <html> <head> <title>Planner</title> <script src="../codebase/library.js" charset="utf-8"></script> <link href="../codebase/library.css" rel="stylesheet" type="text/css" charset="utf-8"> <link href="./styles.css" rel="stylesheet" type="text/css" charset="utf-8"> </head> <body> <script src="../app.js" type="text/javascript"></script> </body> </html>
/server.js
const express = require("express"); const bodyParser = require("body-parser"); const cors = require("cors"); const sql = require("mssql") const app = express(); const port = 4000; app.use(express.json()); app.use(cors()); app.use(bodyParser.urlencoded({extended:true})); app.use(express.static( __dirname + "/public")); app.listen(port, () => { console.log(`Server is running on http://localhost:${port}...`); });
报错信息
GET http://localhost:4000/codebase/library.js net::ERR_ABORTED 404 (Not Found)
Refused to execute script from 'http://localhost:4000/codebase/library.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
Refused to apply style from 'http://localhost:4000/codebase/library.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
GET http://localhost:4000/app.js net::ERR_ABORTED 404 (Not Found)
Refused to execute script from 'http://localhost:4000/app.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
问题原因与解决方法
不需要使用完整路径,问题核心是相对路径的基准发生了变化:
- 直接打开本地
index.html时,路径基准是public目录,../codebase能正确定位到上级目录的codebase文件夹; - 通过Express托管时,
http://localhost:4000对应的是public目录,此时../会指向网站根目录之外,而你的Express只托管了public目录,无法找到codebase和app.js。
推荐解决方法(安全且无需修改HTML路径)
在server.js中添加额外的静态资源托管规则,让服务器能映射这些资源的请求路径:
const express = require("express"); const bodyParser = require("body-parser"); const cors = require("cors"); const sql = require("mssql") const app = express(); const port = 4000; app.use(express.json()); app.use(cors()); app.use(bodyParser.urlencoded({extended:true})); // 托管public目录(原规则) app.use(express.static(__dirname + "/public")); // 托管codebase目录,请求路径/codebase会映射到项目根的codebase文件夹 app.use("/codebase", express.static(__dirname + "/codebase")); // 单独托管app.js,请求路径/app.js会映射到项目根的app.js app.use("/app.js", express.static(__dirname + "/app.js")); app.listen(port, () => { console.log(`Server is running on http://localhost:${port}...`); });
其他可选方法
- 调整文件结构:把
codebase目录和app.js移到public目录下,然后修改HTML里的路径为./codebase/library.js和./app.js,无需修改server.js。 - 使用网站根相对路径:把HTML里的路径改为
/codebase/library.js和/app.js,同时按照上面的方法在server.js中托管对应目录。
内容的提问来源于stack exchange,提问作者squatman

