Nodejs HTTP Createserver-从html文件提供服务时无法预测的javascript执行

时间:2018-09-11 21:42:30

标签: javascript node.js

当我从Node.js Web服务器提供具有一些javascript的html文件时,与从外部源中包含相同的javascript相比,我得到了不同的结果。我已验证,使用javascript内联或外部源直接打开html文件的效果与预期的相同。 在下面的示例中,我在h1标​​签中获得了“ Modified header”,而使用javascript作为外部源,我在h1标​​签中获得了“ Unmodofied header”。 有人可以解释如何解决该问题吗?谢谢。

nodejs Web服务器的代码:

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)

htmlfile.html如下:

<html>
<body>
<h1 id = "header"> Unmodified header</h1>
<!-- <script src="populate_header.js"></script> -->
<script>
  function populate_header () {
    document.getElementById("header").innerHTML = "Modified header"
  }
  populate_header ()
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

简而言之,您的http服务器未配置为在浏览器要求时将populate_header.js发送到浏览器。

在HTML文件中执行此操作时:

<script src="populate_header.js"></script>

您正在告诉浏览器向Web服务器发送对名为populate_header.js的资源的请求。但是您的Web服务器没有一个请求处理程序,该处理程序可以查看正在请求的文件并提供该特定资源。无论请求什么资源,您的Web服务器始终发送htmlfile.html。因此,浏览器要求一个脚本文件并获取一个HTML文件(导致它基本上只是忽略它)。因此,populate_header.js中的Javascript永远不会交付给浏览器,因此其中的脚本也永远不会运行。

当您内联包含脚本时,JavaScript随HTML一起提供,并且可以正常工作,而无需在Web服务器上使用其他路由。

默认情况下,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

Resources not loading in express

ajax request gives a 404 with express server (chrome) loads successfully with firefox without a server?

How to get files above the server directory in Node.js