使用Express最简单的方法提供静态文件服务是什么?

13

我使用了一种相当丑陋的方法:

var app = require('express')(),
    server = require('http').createServer(app),
    fs = require('fs');
server.listen(80);

path = "/Users/my/path/";

var served_files = {};
["myfile1.html","myfile2.html","myfile3.html"].forEach(function(file){
    served_files["/"+file] = fs.readFileSync(path+file,"utf8");
});

app.use(function(req,res){
    if (served_files[req.path]) 
        res.send(files[req.path]);
});

怎样做才是正确的?

6个回答

18

Express已经内置了相应的中间件处理这个问题,它是建立在connect之上的。该中间件本身使用了send

// just add the middleware to your app stack via `use`
app.use(express.static(yourpath));
回答你的评论,没有办法手动选择文件。但是默认情况下中间件会忽略以 . 前缀的文件夹,例如名为 .hidden 的文件夹不会被提供服务。
要手动隐藏文件或文件夹,您可以在 static 之前插入自己的中间件来过滤请求到达它之前的路径。以下内容将阻止从名为 hidden 的文件夹中提供任何文件:
app.use(function(req, res, next) {
  if (/\/hidden\/*/.test(req.path)) {
    return res.send(404, "Not Found"); // or 403, etc
  };
  next();
});
app.use(express.static(__dirname+"/public"));

你能再解释一下吗?这将仅为文件夹中的每个文件提供服务吗? - MaiaVictor
是的,它将为您传递的目录中的每个文件提供服务。 - numbers1311407
3
很好,但有没有手动选择文件或隐藏子文件夹的选项? - MaiaVictor

12
如果你想不使用Express(正如你明确要求的那样“简单”)来解决问题,请查看node-static模块。它允许你像Express的适当中间件一样提供文件夹,但它还允许你只提供特定的文件。在最简单的情况下,它只是:
var http = require('http'),
    static = require('node-static');

var folder = new(static.Server)('./foo');

http.createServer(function (req, res) {
    req.addListener('end', function () {
        folder.serve(req, res);
    });
}).listen(3000);

如果你需要一些例子,可以看看GitHub项目页面,那里有几个例子。
PS:你甚至可以全局安装node-static,并将其用作CLI工具,只需在要提供服务的文件夹内从shell中运行它即可。
$ static

就是这样,:-)!

另外,关于你原来的例子,最好使用流管道而不是同步加载所有文件。


5

2

个人而言,我更喜欢使用nginx来提供文件服务(我也用它进行gzip编码、缓存、SSL处理和负载均衡),而node只提供API。也许这不是你要找的答案,但它提供了有趣的选择。也许你可以看一下这种方法,发现你喜欢它 ;)


1
我对index.html文件做了以下更改,以自动包含文件。这样,当您在文件夹中添加文件时,它将自动从文件夹中获取,而无需在index.html中手动包含该文件。
//// THIS WORKS FOR ME 
///// in app.js or server.js

var app = express();

app.use("/", express.static(__dirname));
var fs = require("fs"),

function getFiles (dir, files_){
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files){
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name, files_);
        } else {
            files_.push(name);
        }
    }
    return files_;
}
//// send the files in js folder as variable/array 
ejs = require('ejs');

res.render('index', {
    'something':'something'...........
    jsfiles: jsfiles,
});

///--------------------------------------------------

///////// in views/index.ejs --- the below code will list the files in index.ejs

<% for(var i=0; i < jsfiles.length; i++) { %>
   <script src="<%= jsfiles[i] %>"></script>
<% } %>

1
如果您想要一个非常简单的方法,那么我想向您展示我的模块(它不仅适用于静态文件)simpleS,使用npm install simples进行安装。
将所有文件放在一个文件夹中,例如files
这就是魔法所在:
var simples = require('simples');

var server = simples(80);

server.serve('files');

/* if you want to catch the acces to a folder and to do something, try this:
server.serve('files', function (connection, files) {
    // Your application logic
    // For example show the files of the folder
});
*/

您不需要关心文件的内容类型,它会自动从文件扩展名检测出来。


simpleS无法提供大约60kb的静态JSON文件。我在文档或搜索中找不到任何可以解决这个问题的配置选项。使用http-server(https://github.com/nodeapps/http-server)效果很好。 - kwcto
@bayfrontconsulting,是的,我找到了这个bug,它与一个损坏的流有关,该流提供最大64KB长度的块并停止了。我在0.4.9版本中修复了这个问题,并带来了许多改进。希望你能再试一次 :) - micnic

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