res.sendfile() doesn't serve javascripts well - node.js

I want to use static file serve without any rendering engine.
I've tried to use:
res.sendfile('public/index.html');
on the '/' GET route, and express middleware for static files on my route:
app.use(express.static(path.join(__dirname, 'public')));
BUT it seems like all of the javascripts which the client asks for are downloaded with index.html file information.
How can I make a successful download of the CSS/JS static files ?
UPDATE:
Here is the route for the "res.sendfile ..." :
app.get('/*', index);
I want all of the requests to the server on any route will get index.html and all of its JS&CSS assosiciated with.

I guess this might help you...
in app.js file...
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.use("/styles", express.static(__dirname + '/public/stylesheets'));
app.use("/scripts", express.static(__dirname + '/public/javascripts'));
app.use("/images", express.static(__dirname + '/public/images'));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', function (req, res) {
res.sendfile(__dirname + '/public/home.html');
});
save the home.html inside the /public folder and JavaScript files in /public/javascripts, images in /public/images, css files in /public/stylesheets folder.
In the HTML file reference should be the words you define(eg: /scripts/home.js)... like this
<link rel="stylesheet" type="text/css" href="/styles/home.css" >
<script src="/scripts/home.js" type="text/javascript"></script>

var express=require("express");
var app=express();
app.use('/', express.static(__dirname + '/website/views/'));
app.set("views",__dirname+'/website/views');
app.get("/",function(req,res){
res.sendfile('index.html');
});
the codes above is mine.i wish to help you.

Why not something like this?
if(req.url == '/') { // Root lookups appear to be mapped to index.html
next();
} else {
fname = [disk location of your website] + req.url;
fs.open(fname, 'r', function(err, fd) {
if(err) {
next();
} else {
fs.close(fd);
res.sendfile(fname);
}
});
}

Well, the simplest solution will be to move app.use(express.static(path.join(__dirname, 'public')))
up before you call app.use(app.router);
This way, the static middleware gets served before the app.get('/*', index);

I've made an assumption here that your routes are declared in this order:
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
If this is indeed the case, then the following suggestion holds:
The problem here is the app.get('/*', …) will intercept all requests that match, which is basically everything. Your static middleware won't get a chance at serving files.
If you remove that route, things should work for you as index.html is already in the public directory and can be served by the static middleware.
For a good explanation of how this works, see the answer to this question: node.js / express.js - How does app.router work?
Update based on additions to the above question:
You've stated this as the current behavior of your server:
it seems like all of the javascripts which the client asks for are downloaded with index.html file information.
You have asked the question:
How can I make a successful download of the CSS/JS static files ?
with this requirement
I want all of the requests to the server on any route will get index.html and all of its JS&CSS assosiciated with.
Your question and requirement are opposed to each other. The server will send back to the client exactly what you tell/configure it to. It will either always send back index.html which is exactly what your requirement states, or it will successfully serve up both index.html and any CSS/Javascript it references which is what your original problem statement was.
In one of your comments below you've stated:
the reason I want to do it, is because I'm using templates, and index.html wraps each template. I'm using angular on the client, and I'm starting to realize that i'll have to use a render engine in order to achieve this. Again, my angular client defines the partial url, and when it sends the request to : '/partial/sample' I need the index.html to wrap the 'sample.html' for instance
My assumptions based on this statement (please correct if wrong)
You are using client side templates
The files you are retrieving from the server are static (i.e., they need to be served up as is from the server)
Your routes are currently declared in this order
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
You are not doing any server side templating (i.e. everything is located under public somewhere)
If these assumptions are correct, the fix is to do what I originally suggested and remove this route:
app.get('/*', index);
If you do this (assuming your resources are referenced correctly):
your index.html will be retrieved as is from the server via the static middleware.
Each css/js file you've referenced in index.html will be returned from the server via the static middleware
Any requests to load template files (such as sample.html) will be serviced by your static middeware and returned to the client without modification

Related

How can I configure express to serve a single home page for many different paths?

This is what I have in mind:
app.use(express.static(path.join(__dirname, 'public')));
app.get('/foo', (req, res) => {
// server the public folder again here
});
app.get('/bar/:id', (req, res) => {
// server the public folder again here
});
I'm trying to deploy a react app that uses routing. The problem is, I need to point all user-facing paths (so, /about, /contact, etc. but not /assets/images/icon.png) back to the homepage, because the react app uses react-router, and once the app is built for production and served as a static site, going to mysite.com/about gives a 404, where it wouldn't have before building.
So it turns out express.static("./path/to/site") can be the only argument to app.use(), or it can be the second argument.
Instead of using app.get(), I need to use app.use() for these other paths.
To capture all paths that weren't handled by default by the static site, I could have something like this:
app.use(express.static(path.join(__dirname, 'public')));
app.use('*', express.static(path.join(__dirname, 'public')));
To be more specific as in the question, I could have something like:
app.use(express.static(path.join(__dirname, 'public')));
app.use('/foo', express.static(path.join(__dirname, 'public')));
app.use('/bar/:id', express.static(path.join(__dirname, 'public')));
In that case, paths that aren't handled automatically by the static site and aren't listed afterwards will result in a 404.

How to modify static file content with express.static?

I am using express.static to serve some static files. I want to modify some files content before return to the client. Below is the source code for static resources under /public path.
app.use('/public', express.static(path.join(__dirname, 'public')))
There are some html files under the public directory and I want to modify the html files before responsing to the client.
How can I do that with static? I know I can add customized middlewares but not sure how. Is there a middleware pattern I can use?
You don't use express.static() for files you want to modify - that's not what it does.
Instead, you create routes for the specific URLs you want to do modification on, then you read the file from disk, make your modification and send it back to the client. There are dozens of template systems for the Express eco-system (such as EJS, Jade, Handlebars, etc...) that are specifically designed to solve this problem. Or, if you really want to write your own, you can just load the file yourself, make whatever modifications you want and then send it.
app.get("/public/somefile", function(req, res) {
fs.readFile(path.join(__dirname, 'public', 'somefile'), function(err, data) {
if (err) {
res.sendStatus(404);
} else {
// modify the data here, then send it
res.send(data);
}
});
});
// put express.static after your other routes that serve from the public
// directory so those other routes are matched first
app.use('/public', express.static(path.join(__dirname, 'public')));

Node.js: How to route website map

I am newbie in Node.js; sorry if my question is dumb:
I wanted to return index.html from server:
var express = require('express');
var app = express();
var path = require('path');
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/elements/hello-world.html', function (req, res) {
res.sendFile(path.join(__dirname + '/elements/hello-world.html'));
});
app.listen(1337);
But there are many assets in the html file that are stored with the appropriate structure on local server. For example, for returning /elements/hello-world.html, it is sufficient to return hello-world.html under elements folder which itself is in root.
But it is not reasonable to write a route for every asset (like csses, images, etc) in index.html.
What is the solution?
looks like you want to serve static files,to serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express.
app.use(express.static('public'))
Now, you can load the files that are in the public directory:
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
taken from the official express docs here
The solution is app.use, like (CoffeeScript):
app.use express.static(public_dir)
app.use '/js', express.static(path.join(public_dir, '/js'))
app.use '/css', express.static(path.join(public_dir, '/css'))
app.use '/images', express.static(path.join(public_dir, '/images'))
app.use '/fonts', express.static(path.join(public_dir, '/fonts'))
app.use '/svgs', express.static(path.join(public_dir, '/svgs'))
In the index.html we pull resources like
<script type="text/javascript" src="/js/primus.js"></script>
<script type="text/javascript" src="/js/app_090.js"></script>
I'm actually not sure if that answers your question, but this is how resource type routing is done in Express.
You need to use the express static module.
app.use(express.static(path.join(__dirname, 'public')));
Create a folder called public in your nodejs root folder, put your index.html and your elements folder inside it.
Now when you load http://localhost/index.html and http://localhost/elements/hello-world.html it should work without any issues.

express serves index.html even when my routing is to a different file

I have a public directory with the files index.html and index-08.html in it.
With the code below, I expect index-08.html to be served. But instead, index.html gets served with a browser request of localhost:3000
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res) {
res.sendFile('public/index-08.html');
});
But if I change the file name of index.html to something else, say not-index.html, then the correct file index-08.html gets served.
Can you please help me understand why this happens ?
This is because you declared app.use(express.static) before app.get('/'). Express checks routes in the order they are declared, and since index.html is a default filename which is used by static middleware, it shows index.html content.
To fix this you may either put app.use(express.static) after app.get('/'), or set index property of static second argument to non-existing file (false doesn't seem to work):
app.use(express.static(path.join(__dirname, 'public'), {index: '_'}));

Express: Redirect '/' to specific route

I'm asking for help after being unable to find a solution through other SO questions.
I'm doing some modular express app. This is the regarding part of my server.js file.
var app = express();
var login = require('./lib/login');
app.use(login);
app.use(express.static(path.join(__dirname, 'public')));
If I hit localhost:3000 It goes straight to public/index.html. But I want it to go to the login route. I've tried something like:
app.get('/', function(req, res){
res.redirect(__dirname + '/lib/login');
});
But it's not even being called since it always goes to index.html. Guess the line app.use(express.static(path.join(__dirname, 'public'))); is doing that from the get go. And Even if I comment that like for testing server's not redirecting to the route so I guess my code's not accurate.
I should add that inside the login route there's a jade template.
Any ideas?
More Information
Structure
/node_modules
/public
/javascripts
/stylesheets
/lib
/login
/views
server.js
Inside the public folder there's the index.html file that's being called. It's there just for testing, it has nothing to do with the real jade files I want to render.
I first added the app.use(express.static(path.join(__dirname, 'public'))); line so I can load my javascripts and my stylesheets in my jade templates with something like script(src='/javascripts/jquery.dataTables.js'). If I remove that original line from my server.js it DOES route / to login but then I can't seem to load those libraries inside javascripts and stylesheets, even if I change script(src='/javascripts/... to script(src='/public/javascripts/...

Resources