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

标签 javascript node.js

当我从我的nodejs 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>

最佳答案

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

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

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

您告诉浏览器向您的网络服务器发送一个名为 populate_header.js 的资源请求。但是您的 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 以查看到底请求了什么,然后发送该资源。它还寻找一个仅响应 GET 请求的 request.method。并且,当发送其他文件时,它会发送 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

关于javascript - Nodejs HTTP Createserver - 从 html 文件提供服务时不可预测的 javascript 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52284578/

相关文章:

javascript - Html 文本区域 - 手动输入新行 (/n) 不起作用

javascript - 期望对象具有所有给定的属性

javascript - Bootstrap 汉堡包在切换后不显示列表元素

javascript - 为什么 lodash deepClone 不对 Function 属性进行深度克隆?

node.js - 在 NodeJS 中访问 SQLite3 数据库

javascript - Webpack - 未捕获的 ReferenceError : webpackJsonp is not defined

node.js - 使用 Atom Shell/Electron 的上下文菜单单击/打开事件?

javascript - 类似苹果的搜索框

javascript - 将对象传递给jquery中的回调函数

javascript - 从 JS 中的 csv 数据制作下拉菜单