gpt4 book ai didi

javascript - 自定义 node.js Web 服务器未完成加载 CSS 和 JavaScript

转载 作者:行者123 更新时间:2023-11-29 21:40:37 24 4
gpt4 key购买 nike

为了 self 提升,我正在尝试编写一个纯 node.js 网络服务器。这个想法是完全避免使用预先编写的中间件或任何非默认的 node.js 模块来加载静态 HTML、CSS 和 JavaScript,并强制自己以纯粹的 node.js 方式学习所有的来龙去脉.

我已经启动并运行它,并测试了几次,它似乎工作得很好,直到我决定通过在静态页面上快速刷新几次来对其进行压力测试。

前 3-4 次重新加载工作正常。之后,静态 HTML 文件调用的 CSS 或 JavaScript 文件均不会加载。

这是我的文件读取代码:

fs.readFile(filename, function(err, contents) {
if(err) {
throw err;
} else {
res.setHeader("Content-Length", contents.length);
res.setHeader("Content-Type", validExtensions[ext]);
res.statusCode = 200;
res.write(contents);
res.end();
}
});

(validExtensions 只是成对的扩展及其适当的 mime 类型的数组。)

当存在 HTML 文件、CSS 文件和 JavaScript 文件时,此函数将在页面加载期间调用三次。同样,它工作正常,直到它突然不工作。然后,如果我再次刷新,一切又好了。

我怀疑这是怎么回事,有时它会在 CSS 或 JavaScript 文件完成之前完成 HTML 文件。

我能想到的唯一解决方法是非常讨厌的。我可以创建一个单独的函数来处理所有非 HTML 文件,并让该过程对剩余文件进行计数。然后我可以在处理 HTML 的函数中使用 while 循环并阻止它执行 res.end() 直到计数为零,但这听起来既丑陋又可能资源消耗。

或者我可以使用同步加载所有非 HTML 文件的(甚至更糟糕的)解决方法,但由于该调用将来自其他异步处理函数,我真的不想这样做。

如果我只是想构建一个静态站点,我会使用 http-server 或 express 或许多优秀的解决方案之一来提供静态文件,但它们都具有广泛的模块依赖性,我正在尝试在没有他们的情况下完成这项工作。

是否有一种优雅而纯粹的方法来确保 res.end() 不会在所有非 HTML 文件完成其操作之前加载 HTML?

编辑:所以任何人都可以看到整个上下文、整个项目及其内容,都在 github 上:https://github.com/GoodDamon/customserver

最佳答案

您的问题在于 customServer.url。如果您打开浏览器的开发工具并检查 app.css 的内容,您会发现偶尔它只会填充以下行:

console.log("自定义服务器加载成功!");

...恰好与您的 app.js 文件的内容相同。巧合?没有。如果您查看 Node 控制台输出,您会时不时地看到:

10/11/2015 5:42:09 PM: New client request: /css/app.css - Method: GET 
10/11/2015 5:42:09 PM: Client requested a file. Testing extension validity...
10/11/2015 5:42:09 PM: File extension .css is VALID. Testing availability...
10/11/2015 5:42:09 PM: New client request: /js/app.js - Method: GET
10/11/2015 5:42:09 PM: Client requested a file. Testing extension validity...
10/11/2015 5:42:09 PM: File extension .js is VALID. Testing availability...
10/11/2015 5:42:09 PM: File is AVAILABLE. Providing to client.
10/11/2015 5:42:09 PM: File is AVAILABLE. Providing to client.

如您所见,浏览器首先请求 app.css,紧接着是 app.js。因为“Providing to Client”两行都在底部,所以您知道您的 Node 服务器还没有处理完第一个请求。客户端最终收到的是 app.js 两次,分别作为 .css 和 .js 文件发送。

这是为什么?每个到达 Node 服务器的客户端请求在理论上应该被隔离到它自己的事件循环中。不应有交叉污染。问题在于 customServer.url,这是您要将传入的 req.url 值分配给的内容。因为它位于两个客户端请求的范围之外,所以每个请求都会覆盖前一个的值。

这对于同步编程来说不是问题,但是 node.js 是完全异步的,并且会在收到所有请求后立即执行所有请求,而不管是否有任何请求仍在等待处理。您的 fs.stat() 调用需要一些时间来执行,并且在执行成功/错误回调之前,另一个请求很有可能已经到达服务器。

tl;dr:这一行 - customServer.getFile(customServer.url, res, ext); 将同一个文件发送到 2 个不同的请求,因为你正在覆盖 customServer.url 每个新请求。 在请求范围内跟踪你的请求 URL!

关于javascript - 自定义 node.js Web 服务器未完成加载 CSS 和 JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33070553/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com