【问题标题】:NodeJS won't Properly load other Files [duplicate]NodeJS不会正确加载其他文件[重复]
【发布时间】:2018-04-26 09:54:02
【问题描述】:

我无法让我的 NodeJS 服务器正确返回 HTML 文件所需的辅助文件。它没有将它们返回到文件中的适当位置,而是做了一些非常麻烦的事情。

这是有问题的代码:

index.js:

var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');


var findFile = (function(basename) {
    var results = {
        contentType: '',
        data: ''
    };

    var dataCSS = {
        dir: '../CSS/',
        contentType: 'text/css'
    };
    var dataHTML = {
        dir: '../HTML/',
        contentType: 'text/html'
    };
    var dataJS = {
        dir: '../JS/',
        contentType: 'text/javascript'
    };
    return function(basename) {
        switch (path.extname(basename)) {
            case '.css':
                fs.readFile(dataCSS.dir + basename, function(err, data) {
                    results = {
                        contentType: dataCSS.contentType,
                        data: data
                    };
                });
                break;
            case '.html':
                fs.readFile(dataHTML.dir + basename, function(err, data) {
                    results = {
                        contentType: dataHTML.contentType,
                        data: data
                    };
                });
                break;
            case '.js':
                fs.readFile(dataJS.dir + basename, function(err, data) {
                    results = {
                        contentType: dataJS.contentType,
                        data: data
                    };
                });
                break;
            default:
                fs.readFile(dataHTML.dir + 'Home.html', function(err, data) {
                    results = {
                        contentType: dataHTML.contentType,
                        data: data
                    };
                });
                break;
        }
        return results;
    };
})();

http.createServer(function(req, res) {
    var myUrl = url.parse(req.url);
    var basename = path.basename(myUrl.path);
    console.log('request url: ' + req.url);

    if (req.url !== '/') {
        console.log('File requested: ' + basename);
    } else {
        basename = "Home.html";
    }
    console.log("Basename: " + basename);
    var data = findFile(basename);
    console.log(data);
    res.writeHead(200, { 'ContentType': data.contentType });
    res.write(data.data);
    res.end();
}).listen(8080);

Home.html:

<!DOCTYPE html>
<html lang="en-US">

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <link rel="stylesheet" type="text/css" href="../CSS/myApp.css">
    <script src="../JS/myApp.js"></script>
    <script src="../JS/myCtrl.js"></script>
</head>

<body>    
    <h2>myApp Test</h2>
    <div class="myApp" ng-app="myApp" ng-controller="myCtrl" ng-init="quantity = 10; cost = 5" my-Directive>
        <p>Color: <input type="text" style="background-color:{{myColor}}" ng-model="myColor" value="{{myColor}}"></p>
        <p>Total in dollar (raw exp): {{quantity * cost}}</p>
        <p>Total in dollar (span): <span ng-bind="quantity * cost"></span></p>
        <p> First Name: <input type="text" ng-model="firstName"></p>
        <p> Last Name: <input type="text" ng-model="lastName"></p>
        <h1>Hello, {{firstName + " " + lastName}}</h1>
    </div>
    Are you even changing?!
</body>
</html>

我的代码的当前运行是这样的:

  1. 我在控制台中使用“node index.js”来启动服务器。
  2. 我第一次在浏览器中导航到“localhost:8080”,它什么也没显示;开发窗口中有一个错误,提示我没有正确格式化标题。这不是真的,因为我在每次访问服务器时都在 findFile 方法中设置了它。控制台读数首先如下所示:

Firefox 中的开发窗口如下所示:

  1. 下一次刷新加载 HTML 页面,但不受辅助文件的任何影响,即使日志显示所有内容都已请求:

此时的控制台日志:

  1. 随后的刷新将页面变成轮盘赌,每个单独的文件代表轮盘上的一个数字。代替 HTML 页面,可能会显示其他页面之一,具有文本文件的外观。我会保留图片;我觉得我做的太多了。

我在这里做错了什么?我应该这样做有不同的方式吗?我什至应该这样做吗?请发送帮助。

谢谢。

【问题讨论】:

  • 有人可能会首先问为什么你使用一个简单的 http 服务器,而不是一个简单的、没有意见的框架,比如 Express,它为你做了很多肮脏的工作,让你的代码更简单,不太容易受到这类错误的影响。
  • 我看到你也有异步问题。您正在使用异步的fs.readFile(),但期望从您的函数返回它的结果,这将永远无法工作。参考How do I return the response from an asynchronous call
  • 你不觉得,你应该把所有的静态js和CSS文件放在一个文件夹里,直接提供它们,而不用读取文件,然后发送响应给客户端吗?
  • @NitishkumarSingh - 你不能那样做。浏览器一次请求这些资源。
  • 对不起,我的措辞令人困惑,我想说的是,与其阅读 CSS 和 js,他也可以直接为它们服务。

标签: javascript html css node.js


【解决方案1】:

fs.readFile 是异步的,这意味着您给它的回调不会立即发生,它会稍后发生。特别是,它发生在findFile 函数返回值之后See this related question for more details.

为了使findFile 正常工作,只要任何fs.readFile 操作完成,它就需要接收回调来调用。还可以查看 promisesasync/await 作为使用回调的更简洁的替代方案。

function findFile(basename, done) {
  switch (path.extname(basename)) {
    case ".css":
      fs.readFile(dataCSS.dir + basename, function(err, data) {
        var results = {
          contentType: dataCSS.contentType,
          data: data,
        }

        // this function is the `function(results)` we call with down there
        done(results)
      })
      break

    case ".html":
    // same as above

    case ".js":
    // same as above

    default:
    // same as above
  }
}

function requestHandler(req, res) {
  // same as before

  findFile(basename, function(results) {
    console.log(results)
    res.writeHead(200, { ContentType: results.contentType })
    res.write(results.data)
    res.end()
  })
}

http.createServer(requestHandler).listen(8080)

【讨论】:

  • 从您的 findFile() 函数中删除 return results。这仍然是错误和误导性的。
  • 啊,感谢您指出这一点。一秒
猜你喜欢
  • 2021-11-11
  • 2015-11-01
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多