在使用自定义中间件时,快速 js 上的静态服务无法正常工作
Posted
技术标签:
【中文标题】在使用自定义中间件时,快速 js 上的静态服务无法正常工作【英文标题】:Static serving on express js not working when also using custom middleware 【发布时间】:2021-12-30 18:19:09 【问题描述】:我正在尝试为我的 express js 网站编写一个中间件,以便我可以使用子域。我还想使用静态图像、css 和 js 服务。我的 html 页面加载得很好,但每当我尝试调用 .js 文件时,页面加载时间很长,并且 js 无法加载。
感谢任何帮助,谢谢! :)
app.use("/assets", express.static(path.join(__dirname, "assets")));
app.get("*", (req, res, next) =>
let host = req.get("host").split(".");
console.log(req.originalUrl);
let url = req.originalUrl.split("/");
url.shift();
console.log(url);
if (host.length > 2)
res.send("myWebsite.com");
else
const pages = Page.getPages();
pages.forEach(page =>
if ((url[0] == "" ? "home" : url[0] ?? "home").toLowerCase() == page.name)
if (url.length == 1 || (url.length == 2 && url[1] == ""))
page.publish(res);
);
);
【问题讨论】:
为了帮助解决 JS 文件的express.static()
问题,我们需要确切知道网页中的 <script>
标签 href
是什么样的,包含网页的完整 URL 是什么页面以及目标 JS 文件在服务器文件系统中相对于服务器运行目录的位置。
另外,page.publish(res)
是做什么的?
感谢 jfriend00 的回复!发布函数执行这行代码:res.sendFile(path.join(__dirname, this.path))
。 Here 是我的文件结构。我希望这会有所帮助:)
仍然需要从<script>
标记中查看实际的src
,然后查看该js 文件在您的服务器文件层次结构中的位置。这两个加上其他一些东西必须匹配,这是使用express.static()
时最常见的错误。
哦,好吧 :) 这是存储库,我想我只需提供所有源代码(当然要减去敏感信息)哈哈。 github.com/markRegg/website
【参考方案1】:
所以,在Pages.html
,你有这个:
<script type="text/javascript" src="/assets/js/Pages.js"></script>
看起来它通常与您的 express.static()
语句(如下所示)兼容,以便从您的 assets/js
文件夹加载 Pages.js:
app.use("/assets", express.static(path.join(__dirname, "assets")));
但是,Pages.js
脚本立即以这样的方式开始:
import Page from '../../Page.js';
当浏览器请求时,这将不起作用。请记住,在浏览器中运行的 Javascript 中的 import
语句中的路径是相对于网页的当前 URL 的。浏览器会尝试将该相对 URL 与网页的 URL 结合起来,然后向您的服务器发出请求以获取该新构建的 URL。
在这种情况下,您最终会收到类似http://somehost/../../Page.js
的请求。但是,您的服务器中没有任何路由可以处理该问题。默认情况下,express.static()
会跳过任何包含../
的路由,因为这可能是一个令人讨厌的安全问题(允许攻击者获取服务器文件系统周围的内容)。因此,您在尝试获取该文件时可能会遇到 404 错误。
您希望浏览器能够加载的所有文件,包括嵌入在其他 JS 文件中的导入,必须位于您的公共 assets
文件夹中(或您已明确启用公共访问权限的其他文件夹,例如 express.static()
)。
仅供参考,如果您查看浏览器控制台,您可能会看到错误消息,这些错误消息会指示您在哪里查找错误。
【讨论】:
【参考方案2】:__dirname 是一个环境变量,它告诉您包含当前执行文件的目录的绝对路径。您必须确保最终捆绑包(您的资产文件夹)存在于该目录中。尝试对资产绝对路径进行硬编码,如果可行,请改用下面的 sn-p:-
app.use("/assets", "express.static(process.cwd() + '/assets'));
【讨论】:
以上是关于在使用自定义中间件时,快速 js 上的静态服务无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
在每个文件上传时使用 dropzone.js 发送自定义数据