I want to define a default route for single page application (angular core) using the express.js. The problem occurs when static file is requested and it does not exist in the routes. In this scenario the default page content is returned instead of the 404 status (Not Found). Sample code:
var path = require('path');
var express = require('express');
var app = express();
var router = express.Router();
router.use(express.static(path.join(__dirname, '/scripts')));
router.get('*', function(request, response) {
response.sendFile(path.join(__dirname, 'views/index.html'));
});
app.use(router);
app.listen(80);
Is exists a good solution to exclude the default route for static files and handle status 404 properly? Would a regular expression for the file urls instead of wildcard be a good approach?
You need to be able to tell if a request is being made for a script file. The problem is that you have a directory structure like this:
/root
/scripts
foo.js
bar.js
And you set up your static handler to allow for users to load scripts like this:
<script src="/foo.js"></script>
What you need to do is set up your folder structure like this:
/root
/static
/scripts
foo.js
bar.js
... then set up your static handler:
router.use(express.static(path.join(__dirname, '/static')));
... then update your script tags:
<script src="/scripts/foo.js"></script>
... and finally update your catch-all route to check if someone is trying to load a script:
router.get('*', function(request, response) {
if (request.originalUrl.indexOf("/scripts/") > -1) {
response.status(404);
response.send('Nah Nah Nah');
} else {
response.sendFile(path.join(__dirname, 'views/index.html'));
}
});
Update: It's a good idea to keep all your static assets in the static
folder. You should group your assets by type: scripts, css, fonts, images, etc. Then you can update your catch-all handler to something like this which will 404 if the URL contains /scripts/
, /css/
, /img/
, or /fonts/
:
var REG_STATIC_ASSET = /\/(?:scripts|css|img|fonts)\//;
router.get('*', function(request, response) {
if (REG_STATIC_ASSET.test(request.originalUrl)) {
response.status(404);
response.send('Nah Nah Nah');
} else {
response.sendFile(path.join(__dirname, 'views/index.html'));
}
});