Node.js HTTP Createserver - 在从HTML文件提供服务时,JavaScript执行不可预测。
Node.js HTTP Createserver - 在从HTML文件提供服务时,JavaScript执行不可预测。
当我从我的Node.js Web服务器提供一个带有一些JavaScript的HTML文件时,与从外部源包含相同的JavaScript相比,我得到不同的结果。我已经验证过直接打开带有JavaScript内联或外部源的HTML文件的效果是一样的,正如预期的那样。\n在下面的示例中,我在h1标签中得到\"Modified header\",而使用外部源的JavaScript时,在h1标签中得到\"Unmodified header\"。\n有人能解释如何纠正这个问题吗?谢谢。\nNode.js Web服务器的代码:\n
var http = require('http') var fs = require('fs') http.createServer(function (request, response) { fs.readFile('htmlfile.html', function(err, data) { response.writeHead(200, {'Content-Type': 'text'}) response.write(data) response.end() }) }).listen(8081)
\nhtmlfile.html如下:\n
Unmodified header
问题的原因是,http服务器没有配置在浏览器请求时将populate_header.js
发送给浏览器。当在HTML文件中包含以下代码时:<script src="populate_header.js"></script>
,浏览器会向服务器发送一个请求,请求名为populate_header.js
的资源。但是服务器没有处理程序来查看被请求的文件并提供该特定资源。无论请求的是什么资源,服务器始终发送htmlfile.html
。所以,浏览器请求了一个脚本文件,却得到了一个HTML文件(导致浏览器忽略它)。因此,populate_header.js
中的Javascript代码从未传递给浏览器,因此其中的脚本从未运行。
解决方法是,将脚本内联包含在HTML中,这样Javascript代码将与HTML一起传递,并且可以正常工作,而不需要在服务器上添加其他路由。
Node.js Web服务器默认情况下不提供任何文件。它仅提供您创建路由处理程序的文件。在使用Express框架时,可以创建一个处理大量静态文件的单个路由(express.static()
正是这样做的)。但是,默认情况下,它不提供任何文件。
如果您需要多个路由处理程序,建议使用非常简单的框架ExpressJS,因为它会节省您很多时间,并且非常轻量级。但是,如果要在现有的小型Web服务器上添加新的路由处理程序,可以像下面这样做:
var http = require('http') var fs = require('fs') http.createServer(function (request, response) { if (request.method === "GET") { let fname; // Look at what resource was requested and match that up // with the appropriate file name // DO not accept any resource requested because that could open up // your server for people to request your actual server code files switch(request.url) { case "/": fname = "htmlfile.html"; break; case "/populate_header.js": fname = "populate_header.js"; break; default: break; } if (fname) { fs.readFile(fname, function(err, data) { if (err) { response.writeHead(404); response.end(); } else { response.writeHead(200, {'Content-Type': 'text'}) response.write(data) response.end(); } }); } else { response.writeHead(404); response.end(); } } }).listen(8081)
在这里,可以看到通过检查request.url
来确定被请求的资源,并发送该资源。它还检查request.method
以仅响应GET请求,并在发送其他文件时发送404响应。
这个问题使用ExpressJS框架会简单得多。
const express = require('express'); const app = express(); // look for matching static resources in the static_files subdirectory app.use(express.static("static_files")); // send the htmlfile.html file when / is requested app.get("/", function(req, res) { res.sendFile("static_files/htmlfile.html"); }); app.listen(8081);
然后,只需将所有静态资源放在主服务器目录的子目录static_files
中,并且Express框架会自动在该子目录中查找与请求的URL匹配的文件。此代码为/
添加了一个自定义路由,专门发送htmlfile.html
文件,您可以根据需要自定义它。
对于更多关于Node.js服务器默认情况下不发送任何文件的讨论,请参阅以下相关答案:
- [Can't load local files when using NodeJS server](https://stackoverflow.com/questions/41656224/41656335#41656335)
- [Resources not loading in express](https://stackoverflow.com/questions/34505215/34506377#34506377)
- [ajax request gives a 404 with express server (chrome) loads successfully with firefox without a server?](https://stackoverflow.com/questions/39282627/39282698#39282698)
- [How to get files above the server directory in Node.js](https://stackoverflow.com/questions/38544628/38544739#38544739)