I have created a nodejs application using the express framework. I have used express.static to serve my static files.
app.use(express.static(path.join(__dirname, '..', 'public')));
There is a route that server the login.html.
// serve login page
app.get('/auth/login', loginPage);
and loginPage function
loginPage(req: any, res: any) {
res.sendFile(path.join(__dirname, '..', '..', 'public', 'login.html'));
}
Now if I directly hit http://localhost:8080/login.html login page gets served with all its css and js files, so static files are getting served.
but when I hit http://localhost:8080/auth/login only login.html is served and the other css/js files showing 404 status.
If I check the request on browser network window request is for http://localhost:8080/auth/css/bootstrap.min.css, this is appending auth prefix.
but when I change URL mapping to /auth from /auth/login then it works fine.
How can I solve this?
I was linking other js and CSS files without using / in href attribute. Like this
<link href="css/bootstrap.min.css" rel="stylesheet">
So I changed all the href by appending the /
<link href="/css/bootstrap.min.css" rel="stylesheet">
and now this is working. Thanks to #Patric
Related
My routes are configured in app.js. The /users route works as expected except when rendering express layouts I cannot access the css files located at ./css/style.css
If I open a page using the /users route, I can see it's looking for /users/css/style.css but I thought setting the directory to static would override this?
app.use('/', require('./routes/index'));
app.use('/users', require('./routes/users'));
app.use(express.static('css'));
First of all, what app.use(express.static('css')); does is to serve statically the files starting from the given path, in this case css.
A good practice is to create a folder called public and use it to serve it's inner files statically. So your static folder should be like this:
-public
-css
-style.css
and your app.js should have app.use(express.static('./public'));
Now, another problem you may be having is the way you cast the paths (url) to load certain files.
Let's say you request http://localhost:PORT/users and the served HTML loads a stylesheet using <link rel="stylesheet" type="text/css" href="PATH">.
You could write the PATH in 2 ways.
css/style.css
/css/style.css
The difference is that the first method will search for the file relative to the path you're already in (e.g http://localhost:PORT/users/css/style.css). The other method will get such file using the 'domain' you are already in as a starting point (e.g http://localhost:PORT/css/style.css.
Hope this helps c:
I figured it out. Added this to my app.js file:
// GET /static/style.css etc.
app.use('/users', express.static(path.join(__dirname, 'public')))
More information here if needed: http://expressjs.com/en/api.html
I'm trying to load assets to my EJS file using express and it does not work. I just get message
Cannot GET /assets/main.css
Even I made loader in my main app:
app.use(express.static(path.join(__dirname, './assets')));
and after printing the path I see that its correct and the files exsists. So after using
<link href="assets/main.css" rel="stylesheet"> I can't reach the file. Where the problem could be?
See Serving static files in Express.
Right now, your app.use(...) statement is saying: I want the directory ./assets to be served whenever I navigate to my app, in other words, when I open my browser to http://localhost, serve whatever is in the folder ./assets.
You are then trying to access the file main.css at http://localhost/assets/main.css. It isn't there, it's at http://localhost/main.css.
You have 2 options:
Change your <link> tag to point to where the asset actually is:
<link href="main.css" rel="stylesheet">
Change your app.use() to host the ./assets folder at a different endpoint:
app.use('/assets', express.static(path.join(__dirname, './assets')));
I am building a single page web application with Ember.js or Backbone.js as front end MVC, express.js(node.js) as back end server.
server/app.js code in short
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '..', 'client')));
app.get('*', function(req, res) {
return res.render('base'); (will sendFile (client/index.html) )
});
It will load up the client/ folder with all the public assets, client folder structure looks like this
- client
-- index.html ( will be rendered as always )
-- app (front end mvc code)
-- assets
-- images
-- styles
When html5 pushstate is enabled by front end MVC, express server is always serving all the matching route as well, which in turn render index.html as always when page is refreshed or url is being manually inserted in the browser.
client/index.html (sample code)
<link rel="stylesheet" href="assets/styles/reset.css">
<link rel="stylesheet" href="assets/styles/base.css">
Here are three different URLs cases
localhost:3000/ (root)
localhost:3000/users || localhost:3000/#/users (hard url)
localhost:3000/users/1 || localhost:3000/#/users/1 ( dynamic segment)
When I defined any static resource as relative path, it works on matching path with root url and hard url on page refresh, it serves resources as
GET /assets/styles/reset.css 304 1ms
GET /assets/styles/base.css 304 2ms
But when I got to localhost:3000/users/1 and refresh the page, I got the wrong resource url, so it failed on loading client/index.html since there are no resources in that path.
GET /users/assets/styles/reset.css 304 2ms
GET /users/assets/styles/base.css 304 6ms
Then I switched to absolute path in
client/index.html (sample code)
<link rel="stylesheet" href="/assets/styles/reset.css">
<link rel="stylesheet" href="/assets/styles/base.css">
it works well even in the dynamic segment url localhost:3000/users/1, all resource serve in the correct url path. but I have an html img tag <img src="assets/images/icons/star.png" alt="star"> in front end mvc template which will be rendered when application boots up. When I load up localhost:3000/users/1 on page refresh, here is what I get
GET /assets/styles/reset.css 304 1ms
GET /assets/styles/base.css 304 2ms
GET /users/assets/images/icons/star.png 304 5ms
I tried with absolute path and relative path in front end mvc template (<img src="/assets/images/icons/star.png" alt="star">), it loads with users prefix no matter what.
I found a solution by tbranyen, but it did not quite work for me. I do not need to setup any cluster at all, what I want is my express server to serve any resource without any prefix when any dynamic segment is being matched. So I wrote this middleware, and it fires correct but still loads the static resource with users/ prefix.
// this route uses the ":user" named parameter
// which will cause the 'user' param callback to be triggered
router.get('/users/:user_id', function(req, res, next) {
console.log('req.params: ', req.params.user_id );
//console.log('#TODO: need to handle the params here');
//next();
return res.render('base');
});
Problem:
When using Express.js as a server, I want every browser request will be handled with response client/index.html, even with dynamic query segment. Currently, whenever url query involves with dynamic query segment /users/:user_id, the response from express server will prefix with users to all the static resources.
For example, when I load the url with dynamic segment localhost:3000/users/1. if i have a resources assets/images/icons/star.png in handlebars template, express server response back /users/assets/images/icons/star.png, but I do not have users folder with the assets. What I want response back /assets/images/icons/star.png.
I tried with absolute path /assets/images/icons/star.png or relative path assets/images/icons/star.png in the handlebars template, it always return with users prefix in the response.
Thanks for any help!
In the <head> of your base template, add this toward the top:
<base href="/">
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
I am using express3 and when I'm trying to load my html/javascript/css files it loads the html without the css.
I'm using this code to load the files -
express.get('/', function (req, res) {
res.sendfile("index.html");
res.sendfile("style.css");
res.sendfile("script.js");
});
So what can I do?
First, link the css and javascript to the page via tags in the header of your HTML
<link rel='stylesheet' href='/path/to/style.css' />
<script src='/path/to/javascript.js'></script>
Be sure that you're using the static middleware in your app.use() section, this will tell Express where to find your static files.
app.use(express.static(__dirname + '/public'));
Now, your Express app should serve your static css and js files.
You link to css and javascript from the html page...
Try looking at the static files example app in the express github repo: https://github.com/visionmedia/express/tree/master/examples/static-files
Basically you make another http request for static files (.js, .css)