Exclude sub directory from static files in express - node.js

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 :)

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')))

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'));

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.

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');
...

Related

return the path of an image that is hosted on my server to show it on the fron-end

currently on my server I have under the path theses images:
/opt/myproject/assets/5259521.jpg
/opt/myproject/assets/5259522.jpg
/opt/myproject/assets/5259523.jpg
I am using nodejs to create my web services. I want to know what is the way to return the path of my images so that the front-end can show them in an img tag.
my restAPI can be accessed by a path:
http://3.89.xx.xx/getImages
Here I would need to return the image paths so that I can display them in my web application.
app.use(cors());
app.options('*', cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json());
// Configuración global de rutas
app.use(require('./routes/index'));
const distDirectory = path.join(__dirname, '/public');
app.get('*', function (req, res, next) {
const file_path = path.join(distDirectory, req.url.split('?').shift());
if (fs.existsSync(file_path)) next();
else res.sendFile(path.join(distDirectory, 'index.html'));
});
app.use(express.static(distDirectory));
thanks
To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express.
The function signature is:
express.static(root, [options])
You need to put all you images in public folder or add the folder name of you choice and then pass the static folder in the express.static middleware.
The name of the folder Public is just a convention, you can set name of folder to anything.
For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public:
app.use(express.static('public'))
And access it like :
http://localhost:3000/assets/5259521.jpg
I am assuming that you the images are under public/assets folder.
To use the static files in Node js
There is a path called 'public' which holds all the files CSS, Bootstrap, Images etc.
add this line to the code
app.use(express.static("public")
if the structure of public folder is
-public
-css
-picture
-images
then you have use images for frontend
<img src = "picture/a.png">
<img src = "image/b.png">
<img src = "image/c.png">
you can have many folders in public folder

Serve out 'static' route with express with redirect and middleware

I am serving out a static url with express 4.0:
app.use('/static-route', express.static('./static'));
And that works great.
However I would like to redirect my users to a url with a query parameter if they hit that route.
ie /static-route -> /static-route?someQueryParam=hello
I would also like to include middleware for that static request. As a concrete example I am using passport and would like to make sure the user is logged in to access that static content.
app.use (and app.get etc . . .) doesn't take two parameters, the first parameter is the route (optional for use), then the rest are all middleware.
app.use('/static-route', function (req, res, next) {
// validation
// redirect
// etc . . .
next();
}, express.static('./static'));
Use global wilcard route[ app.use('/') ] for static content and
Use specific routes [ app.get(/myroute), app.post('/anotherroute')] for dynamic processing using custom logic
//Serves resources from public folder
app.use('/',express.static(__dirname + '/public'));
//Verify the complete directory path - especially slashes
console.log('Static directory '+__dirname + '/public');
app.get('/list', function (req, res) {
res.send('<html><body><h1>Hello World</h1></body></html>'); });

Node.js and Express.JS 4 are not loading linked files when using sendFile method

Using Express.js 4, when I try to use sendFile in order to serve a page that has additional links to javascript files or images, the browser does not load those other assets. If I access the page using a URL it works fine, it is just when I try loading the page with the sendFile method that is the problem.
For example, here is what my code looks like:
var express = require('express');
var app = express();
app.use(express.static('client'));
var path = require('path');
app.get('/game/:gameid', function (req,res) {
var gameID = req.params.gameid;
if (checkGameExists(gameID)) {
res.sendFile(path.resolve(__dirname + '/client/chessBoard.html'));
}
I have tried a bunch of variations like:
res.sendFile(path.resolve(__dirname + '/client/chessBoard.html'));
res.sendFile(__dirname + "/chessBoard.html");`
res.sendFile("chessBoard.html", {root: __dirname + "/client/"});
I have read the Express4 API documentation on sendFile (http://expressjs.com/4x/api.html#res.sendFile), but I am not sure what I am doing wrong.
I am new to Node.js & Express.js so any help would be appreciated!
You can do something like:
app.use('/assets',express.static(path.join(__dirname,'public/assets')));
and also to make it more specific
app.use('/stylesheets',express.static(path.join(__dirname,'public/javascripts/stylesheets')));
Now put your files in the public/assets folder and let's say your HTML file name is index.html.
In the index.html you can link files as src="/assets/js/abc.js".
For more reference you can look into my demo here.
I hope this helps.

How to use static in express js on OS X?

Faced with strange problem: can't setup static folder for express js.
Folder that should be static: /Users/user/Sites/move/assets
Server.js file: /Users/user/Sites/move/app/server.js
URL i use: http://localhost:5001/assets/css/bootstrap.css
Server.js file looks like this:
function Run(config) {
var express = require('express'),
ejs = require('ejs');
var app = express();
app.configure(function() {
// express.static(config.APP_BASE_PATH + '/assets' prints /Users/user/Sites/move/assets
app.use(express.static(config.APP_BASE_PATH + '/assets'));
// Also used
// app.use('assets', express.static(config.APP_BASE_PATH + '/assets'));
});
app.get('/', function(req, res){
res.render('index.html');
});
app.listen(config.APP_PORT);
}
Where is the problem?
It is also possible to create application skeleton with configured static assets, using npm and expres command.
npm install -g express
express --sessions --css stylus --ejs myapp
When you say this:
app.use(express.static(config.APP_BASE_PATH + '/assets'));
It means that a request for /assets/css/bootstrap.css will be looked up as:
config.APP_BASE_PATH + '/assets' + '/assets/css/bootstrap.css'
Which is clearly not what you want.
Instead, you can prefix the middleware declaration:
app.use('/assets', express.static(config.APP_BASE_PATH + '/assets'));
Which means that if a request starts with /assets, the static middleware will take everything after that prefix (so /css/bootstrap.css) and look that up in the directory that you passed.
The starting / is important, otherwise it won't match the incoming request.

express + stylus + jade, nothing gets compiled

I cannot get this simple app.js to work: static files are served but jade and styl files are not compiled.
Here the __dirname ls:
damianomacbook:www damiano$ ls
app.jade app.js app.styl config.xml johnd.jpg
.jade and .styl files are served normally and plain.
Here what happens when curling css and html files (which the middlewares functions are supposed to generate on the fly):
damianomacbook:www damiano$ curl localhost:8080/app.css
curl: (52) Empty reply from server
damianomacbook:www damiano$ curl localhost:8080/app.html
Cannot GET /app.html
What's missing?
Guilty code:
var express = require('express');
var stylus = require('stylus');
var nib = require('nib');
var app = express();
function compile(str, path) {
return
stylus(str)
.set('filename', path)
.use(nib());
}
app.use(express.logger('dev'));
app.set('views', __dirname);
app.set('view engine', 'jade');
app.use(stylus.middleware({
src: __dirname,
compile: compile
}));
app.use(express.static(__dirname));
app.listen(8080);
Your GET /app.html is failing because serving HTML pages is done with the express router, not middleware, and you don't have any routes defined. The static middleware doesn't convert anything (thus the name), so it's not going to serve /app.html unless there's an actual app.html file on disk. To get /app.html working, add:
app.get('/app.html', function (req, res) { res.render('app');});
//or you probably want app.get('/', ...if you want this to be your home page
//you probably also don't want/need ".html" in your URLs as this has fallen out of style
Your stylus problem is the automatic semicolon insertion monster. You must not put the "return" keyword on a line by itself. Your compile function is returning undefined instead of a stylus instance. Keep the compile formatted as it is on the nib documentation and all is well.

Resources