express: how to send html together with css using sendFile? - html

var app = require('express')();
app.get('/', function(req, res) {
res.sendFile(__dirname + "/" + "index.html");
});
<link rel="stylesheet" href="style.css">
I used the above Node.js code to send a html file. To get the html file formatted I need to send another css file (style.css).
My question is: How can I send both of these two files (index.html and style.css) using sendFile() and integrate them together in the client side?

The browser should load style.css on its own, so you can serve that as a route:
app.get('/style.css', function(req, res) {
res.sendFile(__dirname + "/" + "style.css");
});
However, this would get very cumbersome very quickly as you add more files. Express provides a built in way to serve static files:
https://expressjs.com/en/starter/static-files.html
const express = require("express");
const app = express();
app.use(express.static(__dirname));
Keep in mind that if index.html is in the same directory as your server code you will also serve the server code as static files which is undesirable.
Instead you should move index.html, your css, images, scripts, etc. to a subdirectory such as one named public and use:
app.use(express.static("public"));
If you do this, Express will serve index.html automatically and you can remove your app.get("/" as well.

Related

Is it not proper to use the send method to return HTML? Express

I am playing with express, in the past I have used echo with PHP to render out lines of html. In node/express I can add html to a variable and use res.send to return html. That way I can run loops and other things right in the function returning that route. Is this method bad practice? Below I have an example that counts to four.
var router = express.Router();
let a = (req, res, next) => {
let send = `<html>`;
for (let i = 0; i < 5; i++) {
send += `${i}`;
}
send += `</html>`;
res.send(send);
//res.download(filepath)
}
router.get('/', [a]);
module.exports = router;
I think this is a way to go about express router but it's probably not the easiest and it would cause a lot of code on your router page. It all depends on how large and scalable you want your project to be. If you are looking at doing a smaller project then this would work but if you were doing something a little larger e.g. e-commerce site then I would say put your html files in a separate folder and create a views directory for express. I would also suggest using an open source JavaScript Framework such as ReactJS, Vue, or ejs to name a few. You would have to do more code to your express server by adding views as seen in this link
Adding views in express
So instead of sending the html you would do something like res.render('/home'); if that is what you called your home page in your views file.
If that didn't answer your question please let me know.

How to have Express.js server file using router path as root?

I have a directory structure like this
root
private
js
css
index.html
app.js
privateRouter.js
...
In my index.html I reference the js and css files using relative path like this:
<link rel="stylesheet" href="css/index.css"/>
<script src="js/index.js"></script>
On the server side I have a private router checks for authentication before serving these files:
In app.js:
app.use("/private", privateRouter);
in privateRouter.js:
router.use((req, res, next) => {
isAuthenticated(req) ? next() : res.redirect("/");
});
router.get('/', function(req, res, next) {
res.sendFile(require('path').join(__dirname + "/private/index.html"));
});
So now if I visit http://mywebsite.com/private I will get the the index.html, but the request of js/css files from the browser comes back to the server as http://mywebsite.com/js instead of http://mywebsite.com/private/js, thus returns file not found.
Alternatively if I serve files statically, the browser knows to request from /private/js:
app.use("/private", express.static(path.join(__dirname, 'private')));
But I can't server statically because I need to authenticate specific files and not serve all files publicly. And I don't want to have to append private/ before all file references on client side. I don't understand why when serving statically the server knows to use /private as root but when using a router it uses / as root.
How can I keep the url as http://mywebsite.com/private while not having to append private/ in all file references on the client side?
I'm new to express.js and it was also difficult for me to formulate the question. I think I'm fundamentally misunderstanding something about express.js works. Thanks for your help!
You can modify a request's URL using middleware for internal routing:
app.use((req,res,next)=>{
req.url = "/private" + req.url; // prepend "/private" to the url
next();
});
You can also set the base URL using the base tag, which means you only need to specify the base URL once per page.
<html>
<head>
<base href="private">
<link rel="stylesheet" href="css/index.css"/>
<script src="js/index.js"></script>
</head>
</html>
This should then send the requests to:
/private/css/index.css
/private/js/index.js
However, you will still need code to handle these paths, otherwise, you will still get the 404 not found error.

Create Action For Running Nodejs inside HTML

I am new at Node.js
I create a server with node.js I have file like this:
Server.js
Client.js
Index.html
Server configuration is okay. But Inside HTML, I would like to link or an action to run client.js
At HTML, usually we use Link to link a page.
or
run npm with node client.js to run client.js
How I do it at html to run client.js, so if we click a link - client.js will run (the action is same like we do for run at npm node client.js)?
EDIT :
Oke, it looks like difficult to run client.js inside html with click. I changed my question.
I run node.js. And I open a browser (with anything extension html or js) and I would like to run client.js with a click. How do I do that?
I have never hear of such thing.
But I think, if you want to change something in server through frontend, http ajax is a good way.
But according to my acquaintance, when server accept a request from frontend, in a general way,it will run some code,such as function, but not js file.
You could run js file through child_process, it is a module in node, which use to call the shell in your system.
PS, shell.js is a better way if you want to call the shell in nodejs.
see this. https://github.com/shelljs/shelljs
Some server side programming environments work on the basis of having a program, in a file, for each URL that needs to be handled.
Node.js does not work that way.
You write a single server program which handles all the requests and which examines the URL of each one to determine what to do.
const http = require('http');
const server = http.createServer((req, res) => {
console.log(req.url);
if (req.url == "/") {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("The homepage");
} else if (req.url == "/client.js") {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("Whatever you want to do for a request for client.js");
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end("Not found");
}
});
server.on('clientError', (err, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);
While you might store some code in client.js, that filename wouldn't be mentioned to the client. The server would just load it like any other module and then conditionally call functions from it.

Serving Dynamic Webpages with Node.js

I am having a hard time understanding how exactly node.js serves dynamic content.
So let's say we have the following code that renders a home page:
var express = require('express'),
app = express();
app.get('/', function(req,res){
res.render('home.html');
});
However, let's say this home page was supposed to be a user profile in which you are pulling user information from a database, which results in code:
var express = require('express'),
mongoose = require('mongoose'),
app = express();
mongoose.connect('mongodb://localhost/ExampleDB');
app.get('/:id', function(req,res){
User.findOne({_id: req.id}, function (err, user){
var name = user.name;
var profilePic_uri = user.profilePic_uri;
res.render('home.html');
});
So, ideally home.html is just a template page, in which you set maybe the user's profile picture, their name, etc in the route handler. Right, because the idea behind node, is that this app.js should be able to handle pulling the dynamic content from a database at run time. Where I am having trouble is understanding how exactly rendering dynamic pages work with node. The html page is a static page. You can't really render a php or a asp page because, well, that doesn't really make sense does it?
Which leaves me with the question, how is it done?
If you add...
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
...after app=express() has been done then it will now default to the Jade rendering engine if you don't use an extension. Then in your router:
app.get('/', function(req,res){
res.render('home', {
var1: 'val1',
var2: 'val2'
});
});
You'd need to add Jade to your project's package.json file in the dependencies:
"jade": "~1.9.1",
...and then "npm install" in your folder to bring that in.
Then you'd need a file named /views/home.jade with the contents:
doctype html
html
body
p Var1 is #{var1}
p Var2 is #{var2}
You should see--when you visit your home page--that the values have been passed to the Jade rendering engine and expanded in place in the template as 'val1' and 'val2', respectively.
In your case the page is static. Here comes in play template engines (view engines), with this you can render the content of the page dynamic.
Some of the template engines that I remember right now are vash (it's like razor syntax from MVC, I love it) and jade. There are more of them.
Note: You can find in the links I provided how to integrate them with express.
What you are actually asking is not, how it works in Node, but how Express renders templates. Once you understand that you're actually using a feature of the express module, you're probably more aware of what you need to search for to get the correct documentation.
In short: Express features a template rendering engine that does the job for you, very much similar to what ASP or PHP do.
To get to know Node, I'd advise to try to build something without all the libraries first, just to get to know the platform, and to understand why it's feasible to use such libraries or frameworks (such as express).

html and node.js script on the same heroku instance

I'm trying to get something very simple to work with node.js and im kind of stuck at the moment . Hoping someone could help me out with this problem.. Im trying a very simple node.js application.. Basically there is a index.html file which has a form with name as a parameter.. onclick of the button calls a JQuery script which performs a POST request to a node.js script with the NAME value obtained from the html form..
Now the post request is made to the node.js script which runs a HTTP server on its default port.. All that the node.js script does is accepts the parameter and replies with a very trivial response which includes the POST parameter which was sent.. This reponse is caught by JQuery and is given to the user using alert..
So i have index.html and login.js as my two scripts.. Now Im using heroku to host these files.. Problem is once they're uploaded it doesnt really open the html file by default.. it runs the login.js by default..So the HTML is never opened.. Thats probably cause I have a procfile which loads login.js to the dyno.. But if i remove the procfile then i get an error in the logs saying "No web processes running" ..
So basically, long story short , is there a way to have an index.html and a node.js file running on the same heroku instance where the html requests the node.js for info and returns it back..
Here are links to my html and node.js scripts
https://dl.dropbox.com/u/904687/index.html
https://dl.dropbox.com/u/904687/login.js
One option is to use Node.js Express.js to serve the html file and then also handle the login route.
The whole thing would look something like.
file : package.json
{
"name" : "LoginPage",
"version" : "0.0.1",
"dependencies" : {
"express" : "3.x"
},
"main" : "index.js"
}
file : index.js
var express = require('express');
var app = express();
var oneDay = 86400000;
app.use(express.compress());
app.use(express.static(__dirname + '/public', { maxAge: oneDay }));
app.use(express.bodyParser());
app.listen(process.env.PORT);
app.post('/', function(req, res){
var result = req.rawBody;
res.send("hello there world data is " + result);
});
directory structure
package.json
index.js
public
index.html