How to reference css and script files into a node.js app? - javascript

I've read this link Node.js - external JS and CSS files (just using node.js not express) and comprehended somewhat but still do not know where to plug them in, in my case. Consider a 'Hello World' node.js app bellow, 2 lines, link and script, in the head section would not work. I guess because they are not web-reference yet. So, how do I include them in? If I do like the link suggests, would they be outside of the head section?
var http = require('http');
var html =
'<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'+
'<link rel="stylesheet" type="text/css" href="./mystyle.css">'+
'<script src="./myscript.js"></script>'+
'</head>'+
'<body>'+
'<p>Hello World!</p>'+
'</body>'+
'</html>';
http.createServer(function(request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(html);
response.end();
}).listen(80);

You should be using response.writeHead, not request.writeHead.
Also, the current code will return the same file regardless of the js or css request.

Basically, you need the server to deliver your public files. Now the easiest way to do this would be to use express, and set up the static middleware.
However, if you really don't want to use express, I still think the easiest way to do this would be to use the connect static middleware.
Something along the lines of :
var http = require('http');
var static = require('static')('/');
http.createServer(static).listen(80);
This would create a basic web server delivering the files in your / directory.

I got it, finally! Like I said it would help me to understand the basic structure and interaction between node.js and browser. Thank you everyone. Here is the code.
var http = require('http');
var fs = require('fs');
var i = 0;
var html =
'<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'+
'<link rel="stylesheet" type="text/css" href="./mystyle.css">'+
'<script src="./myscript.js"></script>'+
'</head>'+
'<body>'+
'<p>Hello World!</p>'+
'</body>'+
'</html>';
http.createServer(function(request, response) {
i++;
console.log('Request #'+i+': '+request.url);
if (request.url.indexOf('.js') != -1) {
fs.readFile(__dirname + '/misc/myscript.js', function (err, data) {
if (err) console.log(err);
else {
console.log('/misc/myscript.js: fs.readFile is successful');
response.setHeader("Content-Length", data.length);
response.setHeader("Content-Type", 'text/javascript');
response.statusCode = 200;
response.end(data);
}
});
}
else if (request.url.indexOf('.css') != -1) {
fs.readFile(__dirname + '/misc/mystyle.css', function (err, data) {
if (err) console.log(err);
else {
console.log('/misc/mystyle.css: fs.readFile is successful');
response.setHeader("Content-Length", data.length);
response.setHeader("Content-Type", 'text/css');
response.statusCode = 200;
response.end(data);
}
});
}
else {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(html);
response.end();
}
}).listen(80);

Related

Client side js file is not working | node.js

So I just made a HTML page added a script tag with src to a js file and sent the HTML file as response with node js using HTTP module.
But the js file is not working and when I checked the network tab I saw js file is received as text/html file.
Following are the js and html codes.
Server code with node js
const http = require('http') ;
const file = require('fs') ;
const server = http.createServer((req, res) => {
file.readFile('public/login.html', (err, data) => {
if (err) throw err ;
res.writeHead(200, {'Content-Type': 'text/html'}) ;
res.write(data) ;
res.end() ;
})
}) ;
server.listen(5000) ;
front end code : login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<script defer src="js/index.js"></script>
</head>
<body>
<h1>Login</h1>
<form action="" method="post">
<input type="email" name="user" id="user">
<input type="password" name="pass" id="pass">
<button type="submit" name="button" value="login">Login</button>
</form>
</body>
</html>
now when I load the page at localhost:5000, js does not execute and it's received as text/html.
The browser will receive the HTML, see the script tag, and request js/index.js from your server. But your server only sends your HTML file. It doesn't pay any attention to what the browser requested, it just always sends back the HTML. So the script is never sent to the browser, so the browser can't execute it.
Your server code needs to look at req to determine what was requested (looking at url, etc.), and send an appropriate response, rather than always sending back the same content.
Here's a fairly simple example that handles /, /login.html, and /js/index.js paths (making the first two synonyms):
const http = require('http');
const file = require('fs');
const FILENAME_404 = "public/404.html";
const server = http.createServer((req, res) => {
let filename = null;
let contentType = "text/html";
let status = 200;
// What did the browser ask for?
switch (req.url.toLowerCase()) {
case "/":
case "/login.html":
// The login page
filename = "public/login.html";
break;
case "/js/index.js":
// The JavaScript file
filename = "public/js/index.js";
contentType = "text/javascript";
break;
default:
// Something we don't support -- send a 404
filename = FILENAME_404;
status = 404;
break;
}
sendFile(res, filename, contentType, status);
});
function sendFile(res, filename, contentType, status, callback) {
file.readFile(filename, (err, data) => {
if (err) {
// Couldn't read the file, send a 404
if (filename !== FILENAME_404) {
sendFile(res, FILENAME_404, "text/html", 404);
} else {
// Couldn't even find the 404 file, send a minimal plaintext 404
res.writeHead(404, {"Content-Type": "text/plain"});
res.write("The requested resource does not exist on this server.");
res.end();
}
} else {
res.writeHead(status, {"Content-Type": contentType});
res.write(data);
res.end();
}
});
}
server.listen(5000);
Note: This is just an example. If you're going to build anything of any size, you'll want more structure than this. You might look at Express or Koa or others that handle more of the HTTP plumbing, URL routing, etc. for you and have modules available for other things as well.

( NodeJS ) Http server does not load JS/CSS files from folder [duplicate]

This question already has answers here:
How to serve an image using nodejs
(12 answers)
Closed 5 years ago.
Good day ,
I've got a small problem with my NodeJS http server. The server doesn't load the CSS/JS files from folder , only from url and i don't know why. I would appreciate if someone could take some time and give me some tips on what went wrong.
Here is the Server Code :
var http = require("http");
var gs = require("querystring");
var url = require("url");
var fs = require("fs");
var server = http.createServer(function (request, response, err) {
//HTML
if (request.url === "/") {
sendFileContent(response, "HTML/Login.html", "text/html");
console.log("Requested URL : " + request.url + "\n");
}
else if (request.url === "/main") {
sendFileContent(response, "HTML/Main_Home.html", "text/html");
console.log("Requested URL : " + request.url + "\n");
}
// JS / CSS / Other formats
else if (/^\/[a-zA-Z0-9\/]*.js$/.test(request.url.toString(1))) {
sendFileContent(response, request.url.toString().substring(1), "text/javascript");
}
else if (/^\/[a-zA-Z0-9\/]*.css$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "text/css");
}
else if (/^\/[a-zA-Z0-9\/]*.json$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "application/json");
}
else if (/^\/[a-zA-Z0-9\/]*.ts$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "text/javascript");
}
else if (/^\/[a-zA-Z0-9\/]*.png$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "image/png");
}
else if (/^\/[a-zA-Z0-9\/]*.jpg$/.test(request.url.toString()))
{
sendFileContent(response, request.url.toString().substring(1), "image/jpeg");
}
else
{
console.log("Requested URL : " + request.url + "\n");
response.end();
}
});
server.listen(1337, function ()
{
require("console-stamp")(console, '[HH:MM:ss]');
console.log("HTTP Server runs on port : 1337");
});
console.log("Server ready....");
And here is the Send file content function :
function sendFileContent(response, fileName, contentType){
fs.readFile(fileName, function (err, data) {
if (err) {
response.writeHead(404);
response.end("Not Found!");
}
else {
response.writeHead(200, { "Content-Type": contentType });
response.end(data);
}
});
};
And this is how i call the files in html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="../materialize/css/materialize.min.css" media="screen,projection" />
<link type="text/css" rel="stylesheet" href="../CSS/App.css" />
<title></title>
<script type="text/javascript" src="../jquery/jquery-3.2.0.min.js"></script>
<script type="text/javascript" src="../materialize/js/materialize.min.js"> </script>
<script type="text/javascript" src="../Javascript/Main_App.js"></script>
Thank you for your time !
You are trying to implement your own static files server and there so many problems in your implementation even besides those that you're asking about that I think that you need to rethink your approach.
To serve static files it is much easier to use a working solution like express.static - but read below for solutions without Express if you really need it. Example with express.static:
var path = require('path');
var express = require('express');
var app = express();
var dir = path.join(__dirname, 'public');
app.use(express.static(dir));
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
See this answer for more options using connect, express, http and net:
How to serve an image using nodejs
In that answer there are examples of doing what you're trying to do here using express.static, Express without express.static, using connect, using http and using net and even the version that uses raw TCP sockets is not as complicated as your code here. You may want to take a look at it and base your code on these examples.

Node.js server issue - added "/" when looking for files in browser

I'm trying to write my first Nodejs server for getting to know Angular/Node and eventually the whole MEAN stack.
My server is running but there's a problem in my code, for some reason when I enter a non existing file, it should redirect to 404, but it doesn't. For some reason the URL gets a double dash;
How would I go about making the redirect to 404 work?
check this image
Here is my code for the server so far.
var http = require('http'),
fs = require('fs'),
path = require('path'),
root = __dirname + '/public/', //magic var
mime = require('mime');
//Server
var server = http.createServer(function (req, res) {
// Check is root is queried
var fileName = '';
var url = req.url;
if (url === '/'){
url = 'index.html'; // redirect when no file specified
}
fileName = root + url;
// check if file exists
fs.exists(fileName, function(exists){
if (exists) {
serveFile(fileName); // yes
} else {
path = root + '404.html'; //no
serveFile(fileName);
}
})
//serve file
function serveFile(requestFile) {
// maak a stream based on events
var stream = fs.createReadStream(requestFile);
res.writeHead(200, {'Content-Type': mime.lookup(requestFile)});
stream.on('data', function (chunk){
res.write(chunk);
});
stream.on('end', function(){
res.end();
});
stream.on('error', function(err){
console.log('error: '+ err);
});
}
});
server.listen(3000); //server start
console.log('Server gestart op http://localhost:3000 ');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>angular</title>
<link href="https://cdn.jsdelivr.net/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="styles/app.css" rel="stylesheet"/>
</head>
<body ng-app class="bg">
<h1>First name?</h1>
<input type="text" placeholder="Type your name" ng-model='firstName'
class="input-lg"/>
<p>
Hi, {{firstName}}
</p>
<img src="https://static.pexels.com/photos/7720/night-animal-dog-pet.jpg" height="100px" width="100px"/>
</body>
<script type="text/javascript" src="https://cdn.jsdelivr.net/angularjs/1.5.5/angular.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/angularjs/1.5.5/angular.min.js"></script>
</html>
Could anyone tell me what's going wrong here?
Thanks in advance!
get rid of the '/' after public:
root = __dirname + '/public'
It is the default behaviour of Node JS. ie. If you request for xxx.com/sample.txt, then the req.url will be "/sample.txt".
https://nodejs.org/api/http.html#http_message_url
So you have consider that in your code, as #Jordan mentioned, remove the "/".
Your redirect also should work fine.

execute javascript file in dynamically created html page with nodejs webserver

i want to execute the javascript file in the header of an dynamically created html page with a node.js webserver. can't figure out how but must be possible.
var http = require('http');
var url = require('url');
function processRequest(request, response) {
"use strict";
var pathname = url.parse(request.url).pathname;
console.log('Requested ' + pathname);
response.writeHead(1000, { 'Content-Type': 'text/html' });
response.write('<!DOCTYPE html><html ><head>');
response.write('<meta charset="utf-8">');
response.write('<title>' + 'Yay Node!' + '</title>');
response.write('<link rel=stylesheet href=../styles/styles.css rel=stylesheet />');
response.write('<script src=script.js type=text/javascript></script>');
response.write('</head><body>');
response.write('<h1><tt>' + 'jan' + '</tt></h1>');
response.write('<script type="text/javascript">test()</script>')
//response.write('<script type="text/javascript">script.onload = function () { alert("from html Node!")}; </script>')
response.write('<input id="clickMe" type="button" value="clickme" onclick="test()" />')
response.write('</body></html>');
response.end();
};
http.createServer(processRequest).listen(8888);
script.js:
document.onload = function () { alert('load Node!'); };
test = function() { alert('test Node!') };
the problem is, that your browser can't find script.js
When it tries to get http://localhost:8888/script.js node answers with an html file that is the same as http://localhost:8888/.
In order for node to correctly serve the script file, you need to check the path and send the correct file.
add something like this to your processRequest function
if (pathname === '/script.js') {
//code to send script
} else {
//code to send html
}
you would have to do the same for the styles.css file as well
if you don't want to hardcode every file in your page, I would recommend using the npm module express
var express = require('express'),
app = express(),
server = require('http').createServer(app);
app.use('/', express.static(__dirname + '/static');
server.listen(8888);
this code will automatically send the files in /static when the browser requests them.
if you want to create a dynamic page, you can add this between the app.use and the server.listen
app.all('/somedynamicurl', function (request, response) {
//Dynamic page
});
now, if someone goes to http://localhost:8888/somedynamicurl they'll get this dynamic page.
I'd also recommend reading the express guide and the express docs
this works. thanks to Ferdi265.
// http://www.cburch.com/cs/340/reading/nodejs/
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var mimeTypes = {
'.js': 'text/javascript',
'.html': 'text/html',
'.css': 'text/css'
};
function processRequest(request, response) {
"use strict";
var pathname = url.parse(request.url).pathname;
console.log('Requested ' + pathname);
var lookup = path.basename(decodeURI(request.url)), //|| 'index.html',
f = lookup;
fs.exists(f, function (exists) {
if (exists) {
fs.readFile(f, function (err, data) {
if (err) {
response.writeHead(500);
response.end('Server Error!'); return;
}
var headers = {
'Content-type': mimeTypes[path.
extname(lookup)]
};
response.writeHead(200, headers);
response.end(data);
});
// return;
}
else {
response.writeHead(1000, { 'Content-Type': 'text/html' });
response.write('<!DOCTYPE html><html ><head>');
response.write('<meta charset="utf-8">');
response.write('<title>' + 'Yay Node!' + '</title>');
response.write('<link rel=stylesheet href=../styles/styles.css rel=stylesheet />');
response.write('<script src=script.js type=text/javascript></script>');
response.write('</head><body>');
response.write('<h1><tt>' + 'jan' + '</tt></h1>');
response.write('<script type="text/javascript">test()</script>')
//response.write('<script type="text/javascript">script.onload = function () {
alert("from html Node!")}; </script>')
response.write('<input id="clickMe" type="button" value="clickme"
onclick="test()" />')
response.write('</body></html>');
response.end();
}
});
};
http.createServer(processRequest).listen(8888);

How could this basic HTML be externalized from Node.js?

Currently have the following Node.js architecture: index.js + server.js + router.js + requestHandlers.js
HTML is currently embedded in requestHandlers.js, effectively making Node.js the View & Controller.
What is an easy way for the HTML be externalized?
requestHandlers.js:
var querystring = require("querystring"),
fs = require("fs");
function start(response, postData) {
console.log("Request handler 'start' was called.");
var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" '+
'content="text/html; charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" method="post">'+
'<textarea name="text" rows="20" cols="60"></textarea>'+
'<input type="submit" value="Submit text" />'+
'</form>'+
'</body>'+
'</html>';
response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
}
function upload(response, postData) {
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("You've sent the text: "+
querystring.parse(postData).text);
response.end();
}
exports.start = start;
exports.upload = upload;
exports.show = show;
I'd reccommend you not to re-invent the wheel and use some framework, like express.
But if you want to do it your way, then you should use some templating engine, like dust / mustache /jade and put all your html into separate template files.
Then, when you handle your request, you use file input/output , to read those files, pass them through template engine, and send the result to client.
you could do something like this
fs = require('fs')
fs.readFile('./views/index.html', 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
//data now contains the content of index.html, do what you want with it
});

Categories