Node.js 网站根目录

4

我原本以为在运行nodejs Web服务器时,Web的根目录是包含实现Web服务器的js文件的文件夹。因此,如果你有C:\foo\server.js并运行它,“/”将指向C:\foo,“/index.htm”映射到C:\foo\index.htm。

我有一个名为server.js的文件和一个同级的default.htm文件,但当我尝试加载/default.htm的内容时,找不到该文件。绝对文件路径可以工作。

“/”在哪里,什么控制它呢?


简化后的复现步骤如下:

var fs = require('fs');
var body = fs.readFileSync('/default.htm');

我注意到它正在寻找这个

Error: ENOENT, no such file or directory 'C:\default.htm'

所以“/”映射到C:\

是否有一种方法来控制Web根目录的映射?


我注意到相对路径确实可以工作。所以

var fs = require('fs');
var body = fs.readFileSync('default.htm');

成功了。

我相信我的困惑源于我的原始实验项目文件恰好位于驱动器的根目录。这允许对 /default.htm 的引用正确解析;只有在将事物移动到一个文件夹中以将它们置于源代码控制之下时,才会暴露出这个问题。

我一定会研究一下express,但你没有回答我的问题:是否可以重新映射Web根目录,如果可以,如何操作?

顺便说一下,这是 server.js 目前的样子。

var http = require('http');
var fs = require('fs');
var sys = require('sys');
var formidable = require('formidable');
var util = require('util');
var URL = require('url');
var QueryString = require('querystring');
var mimeMap = { htm : "text/html", css : "text/css", json : "application/json" };
http.createServer(function (request, response) {
  var body, token, value, mimeType;
  var url = URL.parse(request.url);
  var path = url.pathname;
  var params = QueryString.parse(url.query);  
  console.log(request.method + " " + path);  
  switch (path) {
    case "/getsettings":
      try {
        mimeType = "application/json";
        body = fs.readFileSync("dummy.json"); //mock db 
      } catch(exception) {
        console.log(exception.text);
        body = exception;
      }
      break;  
    case "/setsettings":
      mimeType = "application/json";
      body="{}";
      console.log(params);
      break;  
    case "/": 
      path = "default.htm";
    default:
      try { 
        mimeType = mimeMap[path.substring(path.lastIndexOf('.') + 1)];
        if (mimeType) {
         body = fs.readFileSync(path);
        } else {
          mimeType = "text/html";
          body = "<h1>Error</h1><body>Could not resolve mime type from file extension</body>";
        }
      } catch (exception) {
        mimeType = "text/html";
        body = "<h1>404 - not found</h1>" + exception.toString();
      }
      break;
  }
  response.writeHead(200, {'Content-Type': mimeType});
  response.writeHead(200, {'Cache-Control': 'no-cache'});
  response.writeHead(200, {'Pragma': 'no-cache'});
  response.end(body);  
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');

我不完全确定你所说的“routes”是什么意思,但我猜测setsettings和getsettings可能是你所指的内容,如果我理解错了,请纠正我。


Nodejs似乎不支持任意映射Web根目录。

唯一需要做的就是在使用文件系统之前,在绝对Web路径前加上一个点:

var URL = require('url');
var url = URL.parse(request.url);
var path = url.pathname;
if (path[0] == '/')
  path = '.' + path;

你能发布一下server.js文件的内容吗? - Aaron Powell
1个回答

4

虽然你说的没错,服务器的根目录确实是当前工作目录,但是Node.js不会直接传递给文件系统上的文件,否则这可能会带来一定的安全风险。

相反,你需要提供路由信息,然后再为所请求的内容提供相应的内容。

例如一个简单的服务器:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

这个程序只会捕获任何请求并以同样的方式进行响应(但不会读取文件系统)。

如果您要提供文件内容,则需要指定一些方法将该文件读入响应流中,这可以通过以下几种方式完成:

  1. 您可以使用fs API在磁盘上查找文件,将其内容读入内存,然后将其管道传输到响应。这是一个相当繁琐的方法,特别是当您开始获取更多文件时,但它确实允许您非常直接地控制应用程序中发生的情况。
  2. 您可以使用像express.js这样的中间件服务器,我认为这是更好的做法来完成您想要做的事情。关于在StackOverflow上使用Express的问题和答案有很多,这是一个很好的静态服务器示例,这正是您所描述的。

编辑

随着问题的澄清,原因是:

var body = fs.readFileSync('/default.htm');

认为文件在 C:\default.htm 的原因是你使用了 绝对路径 而不是 相对路径。如果你使用了:

var body = fs.readFileSync('./default.htm');

那么它就会知道你想要相对于当前工作目录进行操作。 /从分区根目录开始,而 ./ 则是 从当前工作目录开始


简而言之,使用Unix语法,Web的根目录是所在驱动器的根目录,没有映射,也不可配置? - Peter Wone
这开始有意义了。我可以在操作系统级别上进行重新映射,所以没有必要让服务器变得复杂。因此,他们选择了KISS原则。实际上,第一次我就做到了这一点,但当时并没有意识到,这也是让我感到困惑的原因。 - Peter Wone
readFilereadFileSync只是文件系统读取器。它们不仅仅是Web的东西,因为Node.js并不严格是一个Web服务器。 - Joe
@PeterWone,路径的问题不仅限于Unix,Windows现在也使用/作为根目录(而且已经有一段时间了),运行cmd并键入cd /,你将会到达驱动器的根目录 :) - Aaron Powell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接