Which headers indicate a request for static assets - node.js

Using Express we see middleware like so:
app.use('/', express.static(path.resolve(__dirname + '/public')));
app.use('/', function(req,res,next){
// if we get here, the request was not for static assets
});
my question is - which headers does Express use to check that the request is for static assets (files, etc)?
I want to replicate some middleware that does what Express does for static assets.

A typical HTTP request does not have any special headers that suggest that a client might be requesting a static asset over something else. In fact, there is concept of a 'static asset' in HTTP. HTTP is completely obviously to an asset being static, or not.
Anything can be 'static' or 'dynamic'. The middleware probably works because it will check the filesystem if a file exists.

Related

I don't understand the logic of express.static(path.join(__dirname, 'public')))

I use this line
express.static(path.join(__dirname, 'public')));
Does it pass to the client post or get request?
Because if i use
express.get("/",function(res,req){
res.send(dataWirhDb);
}
There is no data on the client. If I use post request, I get data from the server.
If I use without
express.static(path.join(__dirname, 'public')))
and send to the client using get request, data is received on the client.
why does this happen?
No, express.static does not execute any requests. It's just a setup function that tells express that it needs to serve static files, and where to find them.
In this case the location is path.join(__dirname, 'public') , which means the public folder within your application directory.
The static files (like css, images, index.html etc.) are served automatically without the need of setting up routes for them. "Served" in this context means that the server sends the file back as a response to a GET request by the client, asking for that file.

How to prevent express server from serving api routes from the static folder

Hi I need some help with how express handles routes.
In setting up my express app, I have something like this:
app.use(express.static('public'));
Next, I mount some api routes:
app.use('/api', myrouter);
app.get('*', function(req, res) {
res.sendFile(path.resolve('public/index.html'));
});
But, when the frontend requests data via an api route, e.g. at 'localhost:3000/api/things', I am seeing in the Express debug logs that at some point (unsure when) it actually tries to serve this request as a static file, like:
send stat "C:\myproject\public\api\things" +230ms
Even though this folder doesn't exist in 'public' and should be solely handled by my api. FYI, the handler for /api/things route is only implemented for the GET method, and does get invoked at some point.
How do I stop express server from also trying to serve api requests from the static folder?
Thanks very much.
Answering my own question... which appears to be a duplicate of this one:
`express.static()` keeps routing my files from the route
So the answer is this one: https://stackoverflow.com/a/28143812/8670745
In short, the app.use() declarations that mount your api routers should appear before the app.use() statements which tell express.static where to serve your static files from. This way, the latter acts as a catchall AFTER api route handling is done. Router engine order matters...
Your answer is misinformed, or rather you've misinterpreted the problem. Your original configuration:
app.use(express.static(__dirname + 'public'));
app.use('/api', myrouter);
Looks absolutely fine because there's no clash between the routes. The threads you've linked too aren't really the same, and I can see why moving the routes in those cases would have worked.
The only thing I'd say is your path to your static folder isn't reliable, you should really use path.join, or actually in your case you can just do express.static('public') - express will infer the folder your app is served from.

Express: Index Route not called when index.html is served statically

node v5 express 4.13.3
What I did:
I was serving out the index.hmtl file when the index route("/") was hit. I then set it the public folder to be sent out as a static file.
What Problem it Caused:
Now that it is static, my index route is no longer entered when the browser opens the index route e.g.(localhost:3000/)
Question:
Is that expected behavior? Is it a good idea to serve index.html statically ?
Is that expected behavior?
Yes. Express will pass a request through the list of middleware (including your own index route), and if one of those can handle the request, it will and the request will finish (it won't get passed to other middleware).
The static middleware can handle the request for the index (presumably because you have an index.html in your public directory), so the request will end there and not get passed to your handler as well.
The order in which requests are passed to middleware is something that you can control. If you want your own index handler to get a higher priority, you should declare it before the static middleware:
app.get('/', function(req, res) {
...
});
app.use(express.static(...));
Is it a good idea to serve index.html statically ?
If it's plain HTML and there's nothing else that needs to be done when it's requested, it's probably best to let the static middleware handle it.

Express JS: how to know if request is for static asset?

I am writing middleware for some specific task, which should not be executed when request is for static assets (from client folder: app.use(express.static(path.join(__dirname, "../client")));)
So how can i know that particular request is for static asset or is being served from "client" folder?
I have below code
app.use(express.static(path.join(__dirname, "../client")));
app.use(someCustomMiddleware());
i am seeing that requests for static assets like for css/js files is still going thru someCustomMiddleware(). My requirement is that someCustomMiddleware() should not process request for static assets.
Just add it before your other routes. If a request is made for a static item then it will go to app.use(express.static(path.join(__dirname, "../client"))); first, and then your routes.
Ex. Let's say your public folder has some css folder with a file style.css in it. Let's say your routes look like this.
app.use(express.static(path.join(__dirname, "../public")));
app.use(someMiddleware);
If you access /css/style.css, it will hit express.static and serve the file, and will not go to that '/' route.

How to use static folder but also use routing in Express?

I'm having a major issue with Routing in Express.
In my project, there is a folder /public.
Inside /folder I have some other folders like
- public
|- user
|- common
Initially, the only way pages were served by my Node.js server was through res.sendFile(../..). The problem was that the .js files and .css files did not know where to go.
So I added
app.use('/', express.static(__dirname + '/public'));
But now the problem is, if I try to visit /user what happens is, that the static version of the index.html file in that folder is returned, and my route defined in the node app is ignored!
This route - and most importantly the auth middleware is never touched!
How do I reconcile the need to serve files from a static folder, but also may have routes of the same name that I want to control more closely?
app.use('/user', userauth, userRoutes);
Assuming /user is some sort of API I don't think express.static was intended to be used that way. I think the best solution would be to use different routes. You could add something like /api/ to the beginning of all your routes or make sure your static files are organized under /css, /js, /partials, etc.
If you absolutely must support /user for static files AND your api calls you will need to ditch express.static and use something like the Accept header with custom middleware that determines what the browser is asking for. Depending on the scenario this may get complicated to support all the variables. A simple example would be something like this:
app.use(function(req, res, next){
// check Accept header to make sure its a JSON request
if(req.accepts('application/json') && !req.accepts('html')) {
// JSON request so forward request on to the next middleware(eventually hitting the route)
return next();
}
// NOT a JSON request so lets serve up the file if it exists...
// TODO use req.path to check if file exists - if not 404 - will also need to map paths
// to /users to check for /users/index.html if you need to support that
var fileExists = false;
return fileExists ? res.sendFile('...') || res.status(404).send('Not Found');
});
You would have to make sure when the client calls /users it sets the Accept header to application/json. Most client side frameworks have a way to do this for all AJAX requests.

Resources