I just started to see a beginner's tutorial on node.js. It uses the following:
const express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(process.env.PORT || 80)
In the address bar it appears as localhost/test.html and not localhost/public/test.html - so in node.js you can control what's on the address bar regardless to the project structure, as it would've been in PHP?
Or app.use is only a one-time declaration, determining where the root is? such as htdocs or /var/www/html. Because you probably can't do both:
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/public/folder'));
With app.use You're attaching middleware.
If You want to use middleware in all routing logic You do it like:
app.use(middlewareHere);
Or You can define exact routing prefix when that middleware will be used:
app.use('/someRouteHere', middlewareHere);
So for Your case by doing:
app.use(express.static(__dirname + '/public'));
You're telling to express to it like:
app.use('/', express.static(__dirname + '/public'));
which means to call express.static middleware in all kinds of routings before processing next route handlers.
If You want to use it like: localhost/public/test.html
You've to attach middleware like this:
app.use('/public', express.static(__dirname + '/public'));
it's more secure that doing like:
app.use(express.static(__dirname + '/'));
because by defining exact route You're isolating static file handling to exact folder and other internal files that may keep sensible data (passwords, creds) cannot be accessible by static handler.
But best practice is keeping static files in assets folder and handling index.html as root route:
app.use('/assets', express.static(__dirname + '/assets'));
const indexFile = fs.readFileSync(__dirname + '/assets/index.html');
app.all('/', (req, res) => res.status(200).send(indexFile);
P.S. I recommend You to read official manual to understand routing logic.
UPDATE:
This part does not relate directly to Your question, it's for Your comment.
It's just an example. More detailed about how and why and etc read docs and google it. (:
Let's say You want to get data from database and inject that data to placeholders in .html files.
So it will be like this:
const ejs = require('ejs');
app.set('view engine', 'html');
app.engine('html', ejs.renderFile);
app.set('views', __dirname + '/assets'); // since You want to keep html and other static files together
app.use('/assets', express.static(__dirname + '/assets'));
app.get('/profile', (req, res) => {
const userId = req.session.userId;
db.query(
'SELECT * FROM users WHERE id = ? LIMIT 1',
[userId],
(error, rows) => {
cons user = rows[0];
res.render('profile', {user}); // passing user object to view
});
});
And in Your profile.html :
<html>
</head>
<link rel="stylesheet" type="text/css" href="/assets/css/styles.css" />
</head>
<body>
Hello <b><%= user.username %></b>
</body>
</html>
Mini ejs tutorial about looping and etc in terms of php short open tags example:
<% let counter = 0; %>
<% while(counter < 100) { counter++; %>
<%= counter %>
<% } %>
Related
I have some plain HTML/CSS files in my frontend folder and the ejs files in the views folder and every other ejs file loads perfectly but the index.ejs file
I don't know what I am doing wrong here
This is my server.js: (this is a basic version of my server file)
const app = express();
app.set('views', __dirname + '/views');
app.set("view engine", "ejs");
app.use(express.static(__dirname + "/frontend"));
app.get("/", (req, res) => {
res.render("index");
});
//The below file loads perfectly. (requireAuth is a authentication middleware)
app.get("/create", requireAuth, (req, res) => {
res.render("create");
});
Also both the files index.ejs and create.ejs are very similar
If anyone requires any extra details then they can comment down.
You've defined static middleware for / (root path) and the index page is also defined for root path, but because static middleware is defined early, express tries to find and return static file instead of rendering index page.
You have two variants here:
Define static middleware for some path different than root:
app.use("/public", express.static(__dirname + "/frontend"));
Don't use root path for index page: app.get("/index", (req, res)...
I use this function to send html file to client, but in client I get nothing (blank page) without error. Something I wrong?, please help?
var express = require('express');
var fs = require('fs');
var app = express();
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express);
app.get('/test', function(req, res) {
fs.readFile(__dirname + '/views/test.html', 'utf8', function(err, text){
res.send(text);
});
var port = process.env.PORT || 80;
var server = app.listen(port);
console.log('Express app started on port ' + port);
My test.html file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style something here </style>
<title>Test</title>
<script src="..."></script>
</head>
<body>
<div> Somthing here </div>
<script type="text/javascript">
//something here
</script>
</body></html>
Try your code like this:
var app = express();
app.get('/test', function(req, res) {
res.sendFile('views/test.html', {root: __dirname })
});
Use res.sendFile instead of reading the file manually so express can handle setting the content-type properly for you.
You don't need the app.engine line, as that is handled internally by express.
you can render the page in express more easily
var app = require('express')();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.get('/signup',function(req,res){
res.sendFile(path.join(__dirname,'/signup.html'));
});
so if u request like http://127.0.0.1:8080/signup that it will render signup.html page under views folder.
After years, I want to add another approach by using a view engine in Express.js
var fs = require('fs');
app.get('/test', function(req, res, next) {
var html = fs.readFileSync('./html/test.html', 'utf8')
res.render('test', { html: html })
// or res.send(html)
})
Then, do that in your views/test if you choose res.render method at the above code (I'm writing in EJS format):
<%- locals.html %>
That's all.
In this way, you don't need to break your View Engine arrangements.
The "../" is considered malicious and will result in ForbiddenError: Forbidden at SendStream.error... exception.
The way to go is using a path module:
var path = require('path');
res.sendFile(path.resolve('views/auth/success.html'));
var app = express();
app.get('/test', function(req, res) {
res.sendFile(__dirname + "/view/test.html")
});
Here __dirname, gives you the current path where your files are saved. So in res.sendFile(), we first tell our current location by __dirname + (then we locate the specific file which should we shown on the home page i. e ) "vies/test.html".
Follow this simple process and send html file ->
res.sendfile("views/home.html"); // don't use capitla latter F with sendFile you must be use small letter f
example : sendfile();
As my username implies, I'm new to node.js. I'm trying to learn it. As part of this process, I'm working to setup a basic web site. This web site will show a couple of basic web pages and expose a single REST endpoint. The structure of my project is:
config.js
home.html
start.js
routes.js
server.js
resources
css
style.css
images
up.png
down.png
javascript
home.html.js
start.js has my main server code. That file gets executed via command line using 'node start.js'. Once started, my server begins listening on port 3000. The code in start.js looks like this:
var express = require('express');
var app = express();
var UserProfileHandler = require('./app/handlers/UserProfileHandler');
app.configure(function () {
app.engine('html', require('ejs').renderFile);
app.set('views', __dirname + '/');
app.use(express.logger({ stream: expressLogFile }));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
var routes = {
userProfiles: new UserProfileHandler()
};
function start() {
routeConfig.setup(app, routes);
var port = process.env.PORT || 3000;
app.listen(port);
console.log("SUCCESS: Server listening on port %d in %s mode", port, app.settings.env);
}
exports.start = start;
exports.app = app;
My routes.js file has the following:
function setup(app, routes) {
viewSetup(app);
apiSetup(app, routes);
}
function viewSetup(app) {
app.get('/', function (req, res) {
res.render("/home.html");
});
app.get('/home.html', function (req, res) {
res.render("/home.html");
});
}
function apiSetup(app, routes) {
app.get('/api/userProfiles/:username', routes.userProfiles.getUserProfiles);
}
I am trying to load home.html in a browser window. I attempt this by visiting http://localhost:3000 and http://localhost:3000/ and http://localhost:3000/home.html. Unfortunately, none of these work. In fact, I receive an error that says:
Express 500 Error: Failed to lookup view "/home.html"
I know that I'm close. If I visit http://localhost:3000/api/userProfiles/me I receive a JSON response back like I'm expecting. For some reason, i can't seem to return HTML though. My home.html file looks like the following.
<html>
<head>
<script type='text/javascript' src='/resources/javascript/home.html.js'></script>
</head>
<body>
We're up and running! <img src='/resources/images/up.png' />
</body>
</html>
Its a pretty basic HTML file. Even if the HTML comes back though, I'm concerned the JavaScript file and Image it references won't be accessible. I'm concerned of this because I'm not really sure how paths and such work in Node.
How do I get home.html to work in my Node setup?
Thank you!
as your view file is in same folder as your main file, below changes should make it work
1.change the view folder configuration line
from
app.set('views', __dirname + '/');//wont work
to
app.set('views', __dirname);//will work
2.change view render lines
from
res.render("/home.html");//wont work
to
res.render("home.html");//will work
with both the changes, the view should be working fine
update to below comments.
the issue you mentioned regarding the images,css and js is due to the static folder configuration which should be changed from
app.use(express.static(__dirname + '/public'));
to
app.use(express.static(__dirname + '/resources'));
as your static folder is named resources.
but make sure in your view you are refering the css/js/image files like
eg:
/css/style.css
/images/up.png
/images/down.png
/javascript/home.html.js
from your view file
Also if the above dint work, check if you have given the path correctly and also you can try by taking the
app.use(express.static(__dirname + '/resources'));
before the
app.use(express.methodOverride());
app.use(app.router);
lines like
app.configure(function () {
app.engine('html', require('ejs').renderFile);
app.set('views', __dirname + '/');
app.use(express.static(__dirname + '/public'));
//try changing the position of above line in app.configure and resatrt node app
app.use(express.logger({ stream: expressLogFile }));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
had similar problem in my case is
app.set('./views');
look for the dot, dont know why but the dot will mess it up.
I had it like this
app.set('/views') and no matter what i did couldt find the folder until added the dot.
I am new to node and server-side development in general and started having a look at it today so mind my question. I have looked for suiting answers in previous post, yet somehow every suggested solution was criticized by many users.
I can't serve static scripts/styles due to the following error:
Failed to load resource: the server responded with a status of 404 (Not Found)
I am using express 3.1.0.
Here is my code:
app.js
var express = require('express');
var app = express();
var routes = require('./routes');
app.configure(function () {
app.set('view engine', 'jade');
app.use(express.static(__dirname + '/public'));
});
app.get('/', routes.home);
app.get('/about', routes.about);
app.get('/blog', routes.blog);
app.get('/faq', routes.faq);
app.get('/terms', routes.terms);
app.get('/privacy', routes.privacy);
app.get('/jobs', routes.jobs);
app.get('/press', routes.press);
app.listen(8080);
index.js (routes)
exports.home = function(req, res){
res.render('home', { title: "Home"});
};
exports.about = function(req, res){
res.render('about', { title: "About" });
};
etc...
layout.jade
doctype 5
html
head
title= title
link(rel='stylesheet', href='public/styles/bootstrap.css')
body
block content
br
a(href='../') Home
br
a(href='../about') About
br
etc...
home.jade
extends layout
block content
p Home
When you setup server middlewere it looks for requests at the root unless specified otherwise if you are looking for a stylesheet in "public/styles" you request it at just "/styles"
to make the middlewere answer to requests to /public change it to
app.use('/public', express.static(__dirname + '/public'));
I tried using
app.use('/public', express.static(__dirname + '/public'));
instead of
app.use(express.static(__dirname + '/public'));
and it worked.
However according to the first answer in this post: express.js not serving my image it is not considered good. I can't understand why? And what else would be a better solution?
I want to serve html files from a folder if they exist, otherwise fallback to the dynamic app.
currently I use something like:
var express = require('express');
var app = express()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
server.listen(4444);
app.use("/", express.static(__dirname + '/../WebContent/index.html'));
app.use("/styles", express.static(__dirname + '/../WebContent/styles'));
app.use("/script", express.static(__dirname + '/../WebContent/script'));
//here I would like to define a rule like this:
//app.use("*.html", express.static(__dirname + '/../WebContent/*html'));
How can I achieve this?
Some tutorials use a module called connect. If it's the most elegant solution to my problem, how can I integrate connect to my current code?
You don't have to do anything special.
i'm assuming the WebContent folder is in the root.
And if all your static content are in the same base folder like you've shown, you don't have to specify it multiple times.
app.use(express.static(__dirname + '/WebContent'));
if you have a file called file.html in the WebContent folder you can now access it via the url i.e. localhost:4444/file.html
You are using a lot of boilerplate. It is easier using routes. Here is an example:
var routes = require('./routes');
app.configure(function () {
...
app.use(express['static'](path.join(__dirname, '/../WebContent')));
app.use(app.router);
});
// Routes
app.get('/', routes.index);
routes/index.js:
exports.index = function (req, res) {
res.render('index');
};
Rendering your webapp root outside your project root is very strange. Feels like bad practice. Is this necessary?