使用RESTIFY在Node.js中提供静态文件服务

9

我有一个包含 .html、.js、.png、.css 等文件的多级集合网站。我的网站层次结构如下所示:

index.html
child1
  index.html
  page1.html
  page2.html
  ...
child2
  grandchild1
    index.html
  grandchild2
    index.html
  index.html
  page1.html
  page2.html
resources
  css
    myTheme.css
  img 
    logo.png
    profile.png
  js
    jquery.js
    ...
...

我正在将这个应用迁移到Node.js上运行。我被告知必须使用RESTIFY。目前,我已经为我的服务器编写了以下内容:

var restify = require('restify');
var fs = require('fs');
var mime = require('mime');

var server = restify.createServer({
    name: 'Demo',
    version: '1.0.0'
});

server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());

server.get('/', loadStaticFile);

server.get('/echo/:name', function (req, res, next) {
    res.send(req.params);
    return next();
});

server.listen(2000, function () {
    console.log('Server Started');
});

function loadStaticFile(req, res, next) {
    var filePath = __dirname + getFileName(req);
    console.log("Returning " + filePath);

    fs.readFile(filePath, function(err, data) {
      if (err) {
        res.writeHead(500);
        res.end("");
        next(err);
        return;
      }

      res.contentType = mime.lookup(filename);
      res.writeHead(200);
      res.end(data);

      return next();
    });
}

function getFileName(req) {
    var filename = "";
    if (req.url.indexOf("/") == (req.url.length-1)) {
      filename = req.url + "index.html";
    } else {
      console.log("What Now?");
    }
    return filename;
}

使用这段代码,我可以成功加载index.html。但是我的index.html文件引用了一些JavaScript、图像文件和样式表。通过Fiddler工具,我可以看到这些文件正在被请求。然而,在我的node.js控制台窗口中,我从未看到“返回[js|css|png文件名]”。就像我的node.js网页服务器仅返回index.html文件一样。
我做错了什么?

1
如果您想要添加非 ReST 功能(如静态文件服务),我不明白为什么要使用 restifyexpress 提供了一切您所需的,还有更好的文档,已经在生产中被证实是稳定的,并且有社区支持。 - srquinn
2个回答

16

5

你所提供的文件是否包含相对路径(例如 ../abc.js)?需要使用path.resolve()来获取fs.readFile()真实的路径。

无论如何,文件服务中存在许多陷阱:

  • 无效的 URL (400)
  • 找不到文件 (404)
  • 转义序列 (URL 编码)
  • fs.read() 将文件读入内存 (by @robertklep)
  • 等等

你可以使用现有的静态文件服务中间件。我一直在使用Ecstatic,据我所知它能够正确处理这些问题。

尝试一下吧。

server.use(ecstatic({ root: __dirname + '/' }));

如果失败,您可以参考这个将Restify叠加在Connect / Express之上。

建议使用静态中间件(fs.readFile 的另一个问题是它首先将文件读入内存)。+1 - robertklep

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