在使用自定义中间件时,快速 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 上的静态服务无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Nuxt.js 自定义角色中间件在页面刷新时不起作用

使用自定义中间件后无法再获取

在每个文件上传时使用 dropzone.js 发送自定义数据

Vue JS - vue 组件上的自定义属性会导致 TS 错误

快速视频中的照片上的自定义动画

带有自定义 Http(s) 代理和 Connect.js 中间件的 Node.js 代理