简体   繁体   中英

Node.js, Express and Mongoose serving several static files

With Node.js, Express and Mongoose, I am serving several static files synchronously within multiple sub-directories with the following code (which works fine):

fs.readdirSync(__dirname + "/../../../np-site/themes/default/client/")
    .forEach(function (dir) {
        app.use(express.static(__dirname +
            "/../../../np-site/themes/default/client/" + dir)
        );
    });

However, part of the url must be dynamic depending on a database entry value:

express.static(__dirname + "/../../../np-site/themes/" + theme + "/client/" + dir)

I have tried several different ways, to no avail. The following is the first attempt I made, which made the most sense to me at the time (the App model is a single object that can only be updated and retrieved):

App.find(function (err, appSettings) {
    fs.readdirSync(__dirname + "/../../../np-site/themes/" + appSettings[0].theme +
        "/client/").forEach(function (dir) {
            app.use(express.static(__dirname + "/../../../np-site/themes/" +
            appSettings[0].theme + "/client/" + dir)
        );
    });
});

This however does not work, and no static files are served as a result.

The object that I need to access is available (discovered via console.log), but something is not right.

The browser console does return an infrequent error message stating the MIME type of the files (CSS) is not correct, but I believe this is because the app cannot find correct directories (removing the method altogether has the same result).

I'm thinking that it has something to do with app.use within a Mongoose method, but I am not certain.

Could someone please shed some light towards this frustrated soul? I feel as though I am on the wrong path.

The problem is that you're adding your middleware asynchronously (because App.find() is most likely performing an asynchronous action), which causes your dynamic middleware to get added (probably) after all of your statically defined middleware and route handlers.

Express executes middleware and route handlers in the order that they are added.

The solution would be to delay adding any other middleware or route handlers until after your fs.readdirSync() (but inside your App.find() callback). A simple way to do this is to simply put your other middleware and route handler additions inside a function that you call after your fs.readdirSync() :

var baseThemePath = __dirname + "/../../../np-site/themes/";
App.find(function (err, appSettings) {
  var themePath = baseThemePath + appSettings[0].theme + "/client/";
  fs.readdirSync(themePath).forEach(function(dir) {
    app.use(express.static(themePath + dir));
  });
  setupStatic();
});

function setupStatic() {
  app.use(express.static('public'));
  app.get('/', function(req, res) {
    res.send('Hello world');
  });
  // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM