【问题标题】:Node.js Serving HTML pages and Static contentNode.js 提供 HTML 页面和静态内容
【发布时间】:2016-09-14 21:50:59
【问题描述】:
var express = require("express");
var app     = express();
var path    = require("path");

app.use(express.static(__dirname + '/view'));

app.get('/dashboard',function(req,res){
  res.sendFile((path.join(__dirname + '/dashboard.html'));
});

app.get('/index1',function(req,res){
  res.sendFile((path.join(__dirname+'/index.html'));
});
app.get('/',function(req,res){
  res.redirect('/login');
});
app.get('/login',function(req,res){
  res.redirect((path.join(__dirname + '/login'));
});

app.listen(3000);

console.log("Running at Port 3000");

我的问题是为什么每次用户请求时我都需要检查?

另外,如果我的目录中有100个html文件,我需要通过get方法检查每个文件,然后通过res.sendFile返回页面吗?

【问题讨论】:

  • 这就是所有 Web 服务器的工作方式。当您浏览目录时,甚至您的操作系统也以这种方式工作。是什么让您认为有一种神奇的方法可以在不检查用户输入的内容的情况下确定用户想要什么?
  • 虽然你说的完全正确@slebetman,但我认为 OP - 出于某种原因 - 认为他们必须列出每个静态文件,而不是创建一个服务于中间件的文件。
  • @ClemensHimmer:啊。我看到了静态中间件,以为他在问为什么静态中间件需要检查每个请求的url。因为他的问题是“每次用户请求什么”,而不是每条服务路径。我的错。

标签: node.js express


【解决方案1】:

@OrangeDog 和@Clemens Himmer 所说的都是真的。但是,提供目录中所有文件的最简单方法已经在您的脚本中:

app.use(express.static(__dirname + '/view'));

如果名称与 URL 匹配,它将为您的 view 目录中的所有内容提供服务,例如http://yoursite.com/index.html 将解析为 __dirname + '/view/index.html' 处的文件。

但是,在您的示例路由中,您似乎正在更改 URL 路径以不再匹配文件位置(例如,/login 您想解析为“/login.html”)。您绝对可以编写中间件来处理它并根据模式解析文件,但此时使用已经包含 URL 重写功能的专用 Web 服务器(如之前建议的 nginx)要简单得多。

【讨论】:

  • 你是对的,可能最好坚持基本的东西,因为 OP 似乎很难理解 Web 服务器的基础知识,+1 为简单起见。
【解决方案2】:

不,您不必以编程方式列出所有静态文件。您可以通过将middleware 绑定到服务器的根来动态地为它们提供服务。

这是我完成的一个小型 express.js 脚本,它基本上是一个非常简单的 Web 服务器,可以提供任何内容和漂亮的 HTML。

// This servers a file..
var serveFile = function(filePath, res){
    var options = {
        dotfiles: 'deny',
        headers: {
            'x-timestamp': Date.now(),
            'x-sent': true
        }
    };

    res.sendFile(filePath, options, function (err) {
        if (err) {
            console.log(err);
            res.status(err.status).end();
        }
    });
};

// Serve web files
app.use("/", function (req, res, next) {

    var filePath = (absoluteServePath + req.originalUrl).replace(/\//g,"\\");

    var checkFilePath = function(filePath){
        return new Promise(function(resolve, reject) {
            fs.access(filePath, fs.F_OK, function(err) {
                if(!err){
                    // If FILE / DIR exists check if file or DIR
                    if(fs.lstatSync(filePath).isDirectory() == true){
                        reject();
                    }
                    else{
                        resolve();
                    }

                }else{
                    reject(err);
                }
            });
        });
    };

    checkFilePath(filePath).then(function(){
        serveFile(filePath,res);
    },function(){
        // Check if path ends with a slash
        var endsWithSlash = filePath.substr(filePath.length - 1) == "\\";
        // Check if a index.html exists in the path
        var indexHTMLPath = filePath + ((endsWithSlash == true) ? "" : "\\") + "index.html";

        checkFilePath(indexHTMLPath).then(function(){
            serveFile(indexHTMLPath,res);
        },function(){
            // Check if .html for the path exists
            var plusHTMLPath = filePath +".html";

            checkFilePath(plusHTMLPath).then(function(){
                serveFile(plusHTMLPath,res);
            },function(){
                // Nope, does not exist at all
                next();
            });
        });
    });
});

【讨论】:

  • 哦,绝对不是,如果你能阅读 cmets 和随它发布的文字,你应该明白这个答案的每一点。
  • 另外,我刚刚在代码中添加了一些 cmets,这是对我的帖子的补充——只为你。如果一个 11k 的用户现在看不到这段代码的作用,我会真的感到惊讶 :)
  • 可以看到它的作用,但我不确定它是否有助于 OP 为他们提供完整的复制解决方案。
【解决方案3】:

我的问题是为什么每次用户请求时我都需要检查?

如果您不检查他们的要求,您应该如何向用户提供他们的要求?

如果我的目录中有100个html文件,我需要通过get方法检查每个文件,然后通过res.sendFile返回页面吗?

如果你的意思是你需要为每个文件声明一个单独的路由,那么答案是否定的。快速路由可以是基于模式的,因此您可以定义一个路由,例如整个目录,然后返回请求的特定文件:Simple static HTML server in Node

这一切都导致了 Node.JS not being a great choice for serving lots of static content。您需要注意许多安全和其他问题,而且它的性能不如预期。如果您使用 nginx 或 apache2 服务器来提供这些文件,将动态请求转发到您的 Node 服务器,您可能会过得更好。

Node.js + Nginx - What now?

【讨论】:

  • 我的问题是为什么每次用户请求时都需要检查?如果你不检查那是什么,你应该如何给用户他们要求的东西?为什么我需要检查?假设我通过浏览器 url 请求 index.html 文件,如果该文件存在,它应该存在,否则它应该抛出我错误。由于我是节点新手,我很困惑为什么需要检查
  • "如果文件存在" - 这称为检查。我认为您所说的“检查”实际上是定义一条路线,我的答案的第二部分涵盖了这条路线。
  • 从根本上说,除非您检查,否则您无法知道“index.html”就是您要查找的内容。但正如我所说,我认为你只是用错了词,让自己感到困惑。
猜你喜欢
  • 2015-10-30
  • 2012-09-06
  • 1970-01-01
  • 2016-07-14
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多