List static content on server and return it as JSON using Express

3.8k Views Asked by At

I have a very simple app serving static files:

var express = require('express');
var app = express();
app.use(express.static(__dirname + '/files'));
app.listen(process.env.PORT || 8080);

I'd like to make this app slightly smarter by responding to GET for folders. I mean, to list the full list of files of the folder, in a JSON.

For instance, for a GET at localhost:8080/, I would like the app to return:

[{
  "type" : "file",
  "name" : "file1.ext"
},
{
  "type" : "file",
  "name" : "file2.ext"
},
{
  "type" : "dir",
  "name" : "a-folder"
}]

instead of:

Cannot GET /

Is there a way to extend Express's static behaviour to achieve this? If not, what approach would you recommend?

EDIT: I tried to use the serve-index middleware (formerly directory), which works well but unfortunately returns directly html, when I need raw JSON.

1

There are 1 best solutions below

11
On BEST ANSWER

As said in http://expressjs.com/starter/static-files.html

You need to use express.static:

var express = require('express');
var app = express();
app.use("/files",express.static('files'));
app.listen(process.env.PORT || 8080);

Then you will be able to access the files as:

http://yourdomain.com/files/file.jpg

EDIT I just realized, you need the list of files in the dir.

There you have the answers, then, I´ll mark as duplicate

As commented here, maybe installing node utility glob (npm install glob), and code some express function for GET in /files dir this way:

var express = require('express');
var app = express();
var glob = require("glob")


//EDIT: As you commented, you should add this also here, to allow 
//  accessing the files inside the dir. It should not be a problem as 
//  GET only manages the requests to "/files" url, without a file name    
//  after it.

app.use("/files", express.static("/files"));

app.get('/files', function (req, res) {

//EDIT: USE WALK INSTEAD OF WALK TO GO UNDER CHILD DIRS
glob("*.ext", options, function (er, files) {
  // files is an array of filenames.
  // If the `nonull` option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
  res.send(files);
});


});

var server = app.listen(8080, function () {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

});

WALK MODE: (FOR SUBDIRS, AS REQUIRED)

var express = require('express');
var app = express();
var walk    = require('walk');
var ALLfiles   = [];

app.use("/files", express.static("/files"));

app.get('/files', function (req, res) {

//EDIT: If you need to go under subdirs: change glob to walk as said in https://stackoverflow.com/questions/2727167/getting-all-filenames-in-a-directory-with-node-js/25580289#25580289
  var walker  = walk.walk('./files', { followLinks: false });
   walker.on('file', function(root, stat, next) {
       // Add this file to the list of files
       ALLfiles.push(root + '/' + stat.name);
       next();
   });

   walker.on('end', function() {
    res.send(ALLfiles);
   });

});

var server = app.listen(8080, function () {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

});