Exclude sub directory from static files in express

13,432

Solution 1

You can add your own middleware. Here's what I did to exclude some folders:

app.use('/public', (req, res, next) => {
  if (env !== 'development') {
    var result = req.url.match(/^\/js\/(maps|src)\/.+\.js$/)
    if (result) {
      return res.status(403).end('403 Forbidden')
    }
  }
  next()
})
app.use('/public', express.static(path.join(__dirname, '/public')))

Solution 2

It's possible by adding regular expressions to the first optional param of use method.

According with Express 4.x API path documentation.

Example, I don't want to give access to my secure folder inside public folder:

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

app.use([/^\/public\/secure($|\/)/, '/public'], express.static(__dirname + '/public'));

This will allow you to access all files but not the ones in the secure folder.

You can use it also to restrict a file extension, example files that ends with .js.map:

app.use([/(.*)\.js\.map$/, '/public'], express.static(__dirname + '/public'));

And you also can add multiple rules, like this example where secure folder and files that end with .js.map are ignored from the static folder:

app.use([/^\/public\/secure($|\/)/, /(.*)\.js\.map$/, '/public'], express.static(__dirname + '/public'));

Solution 3

I had a similar problem, which may be the answer you were seeking. Given the following directory:

public
   css/
   images/
   secure/
   index.html

The Express Middleware stack I wanted was this:

1. Static files (except the `secure/` directory)
2. Logging
3. Authentication
4. `secure/` static files

Here's how I solved it:

var express = require('express');

var path = require('path');
var app = express();

// path.join here makes it work cross platform with Windows / Linux / etc
var statics = express.static(path.join(__dirname, 'public'));

function secureStatic(secure) {
  return function (req, res, next) {
    if (/^\/secure/.test(req.path) === !!secure) return statics(req, res, next);

    return next();
  };
}

// add public files
app.use(secureStatic());
app.use(logging());
app.use(authentication());

// add secured files
app.use(secureStatic(true));

This will only serve public files when unauthenticated, and only serve secure files after authentication.

Solution 4

Most solutions above are to use a middleware.

However, there is a just easier way to solve this.

Don't serve static assests directly with the dir public rather than serve dir just what you want to serve with a virtual path prefix .

You can serve like below

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

app.use('/public', __dirname + 'css');
app.use('/public', __dirname + 'images');
...
Share:
13,432

Related videos on Youtube

Ivan Longin
Author by

Ivan Longin

Software developer

Updated on September 14, 2022

Comments

  • Ivan Longin
    Ivan Longin over 1 year

    Is there any way to exclude sub directory from express static middleware in express 4.8.5.

    For example if I have :

    app.use(express.static(__dirname + 'public'));
    

    And my public directory is like this :

    - public  
       - css
       - images
       - scripts
       - index.html
       - exclude_me
            - scripts
            - views
            - index.html
    

    So I need to exclude last sub directory and when user does :

    GET /exclude_me
    

    It should call my route rather than returning directory automatically.

    I can't just remove it from public dir because it depends on stuff inside it because public directory is angular application and exclude_me is another angular application that fetches scripts from /exclude_me/scripts AND from /public/scripts.

    I know it is little confusing but it is how it is and I cannot just remove it from public dir because it won't see public/scripts any more which are needed and I cannot leave it because I cannot authorize it then (all authorization is in public/scripts)

    If there is some smarter way to do this, feel free to let me know :)

    • Explosion Pills
      Explosion Pills about 9 years
      What do you mean stuff inside depends on it?
    • Ivan Longin
      Ivan Longin about 9 years
      I've added additional information in question
  • Nikaoto
    Nikaoto almost 5 years
    Underrated answer
  • Rajan
    Rajan almost 3 years
    This answer looks more efficient than the accepted answer
  • Rafe
    Rafe over 2 years
    it is recommended to keep css, js and images in separate directories. so it's better to use /public/css and /public/images mappings