How to avoid building an entire HTML page in the server? - javascript

If you look at code below on the client.on method, I res.write the entire output file because I did not know how to get the message to display with the html file. Is there a similar way of doing this rather than res.writing anything? Res.write is also very slow while when I used res.send it was very fast. Is there any other way I can do this? I am fairly new to node js
//Sending UDP message to TFTP server
//dgram modeule to create UDP socket
var express= require('express'), fs= require('fs'),path = require('path'),util = require('util'),dgram= require('dgram'),client= dgram.createSocket('udp4'),bodyParser = require('body-parser'),app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(express.static('public'));
//Reading in the html file for input page
app.get('/', function(req, res){
var html = fs.readFileSync('index2.html');
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
});
//reading in html file for output page
app.get('/output', function(req, res){
var html = fs.readFileSync('index3.html');
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
});
//Recieving UDP message
app.post('/output', function(req, res){
//Define the host and port values of UDP
var HOST= '192.168.0.136';
var PORT= 69;
//Reading in the user's command, converting to hex
var message = new Buffer(req.body.number, 'hex');
//Sends packets to TFTP
client.send(message, 0, message.length, PORT, HOST, function (err, bytes) {
if (err) throw err;
});
//Recieving message back and printing it out to webpage
client.on('message', function (message) {
res.write('<html>');
res.write('<head>');
res.write('<meta name="viewport" content="width=device-width">');
res.write('<link rel="stylesheet" type="text/css" href="style.css" media="screen" />');
res.write('</head>');
res.write('</body>');
res.write('<img src="logo.png" alt="rolls royce logo">');
res.write('<ul>');
res.write('<li>Input</li>');
res.write('<li><a class="active" href="/output">Output</a></li>');
res.write(' </ul>');
res.write('</br></br>')
res.write('<div>');
res.write(' <h4>Output is:</h4>');
res.write(message.toString());
res.write('</div>');
res.write('</body>');
res.write('</html>');
});
});
//Setting up listening server
app.listen(3000, "192.168.0.136");
console.log('Listening at 192.168.0.136:3000');

You could write an HTML template, save it into a part of the file system which is accessible from the server, then return it to the HTTP client feeded with the right value.
You could write your own template engine (and use regular expressions to make the correct substitutions), or you could you use Jade for instance.
client.on('message', function(message) {
fs.readFile('/etc/templates/message.jade', function(_, template) {
let body = jade.compile(template)({
message: message.toString()
});
return res.end(body);
});
});
Where message.jade might be
doctype html
html
body
h4 Output is: #{message}

Related

How to send variables from Node.js to Socket.io and display on local webpage?

I'm working on a project where my job is to use Node.js and Socket.io to read a text file (contain 3 real time readings) and got the data in 3 variables, then send them to Socket.io and get them displayed on the website continuously without having to refresh it. I ran my codes, it did not give any errors, but it did not display anything on the website either. So I don't know what is wrong in my code. I need help with passing variables from Node.js to Socket.io and get them displayed on the my web page.
This is my server file:
var http = require('http').createServer(handler); //require http server, and cr$
var fs = require('fs'); //require filesystem module
var io = require('socket.io')(http) //require socket.io module and pass the htt$
http.listen(8080); //listen to port 8080
function handler (req, res) { //create server
fs.readFile(__dirname + '/index.html', function(err, data) { //read file inde$
if (err) {
res.writeHead(404, {'Content-Type': 'text/html'}); //display 404 on error
return res.end("404 Not Found");
}
res.writeHead(200, {'Content-Type': 'text/html'}); //write HTML
res.write(data); //write data from index.html
return res.end();
});
}
io.sockets.on('connection', function (socket) {
setInterval(function(){
var array = fs.readFileSync('report.txt').toString().split("\n");
var volt = (array[0]);
var power = (array[1]);
var temp = (array[2]);
socket.emit('volt',{'volt': volt});
socket.emit('power',{'power': power});
socket.emit('temp',{'temp': temp});
}, 1000);
});
index.html file :
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script>
var socket = io('http://10.117.230.219:8080');
socket.on('volt', function (data) {
$('#volt').text(data.volt);
socket.on('power', function (data) {
$('#power').text(data.power);
socket.on('temp', function (data) {
$('#temp').text(data.temp);
});
</script>
<div id="volt"></div>
<div id="power"></div>
<div id="temp"></div>
</body>
You are missing some tags on your HTML page including HTML and head. You are also missing a closing )} for each socket.on(...) call in your script. This is what it should look like:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script>
var socket = io('http://localhost:8080');
socket.on('volt', function (data) {
$('#volt').text(data.volt);
})
socket.on('power', function (data) {
$('#power').text(data.power);
})
socket.on('temp', function (data) {
$('#temp').text(data.temp);
})
</script>
</head>
<body>
<div id="volt"></div>
<div id="power"></div>
<div id="temp"></div>
</body>
</html>
This should do it.

Send new HTML page and make GET request to it after POST request from original page

I'm new to Node.js and JavaScript. I have a specific problem but mostly need advice on the best solution.
I'm running a Node server. I want the client to be able to submit a string to the server, then the server to display a new HTML page that shows the string data.
I'm using Express and Socket.io.
In the following files, the client sees index.html, then after submitting the form it sees return.html. I print the input string to the console, and the output is as expected (whatever the user enters). But the return.html is never updated with the input string.
I also tried sending the return.html page and the change_result call in an async series, but the sendFile function never ends and the second function in the series is never called. In previous attempts it worked intermittently with a setTimeout around the emit('change_result') function.
Why doesn't the call to change_result do anything? I used the same technique to update the headings of the original index.html in previous versions. Should I be routing to localhost.../return.html and sending the post data there, or something like that?
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var bodyParser = require('body-parser') //for POST request
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
server.listen(8080, function() {
console.log("Server running on port 8080.");
});
var dir = __dirname;
app.get('/', function(req, res) {
res.sendFile(dir + '/index.html');
});
app.post('/', function(req, res) {
var query1=req.body.input1
console.log("Server: In post request.")
console.log(query1);
res.sendFile(dir + '/return.html');
io.emit('change_result', {
result: query1
});
});
index.html
<!DOCTYPE html>
<html>
<body id="body">
<form method="post" action="http://localhost:8080">
String: <input type="text" name="input1" id="input1" />
<input type="submit" id="button1" value="Submit" />
</form>
</body>
</html>
return.html
<!DOCTYPE html>
<html>
<body id="body">
<p id="heading1">Result: </p>
<script>
document.addEventListener('DOMContentLoaded', function() {
var socket = io();
socket.on('change_result', function(data) {
document.getElementById('heading1').innerHTML = "Result: \""+data.result"\"";
});
});
</script>
</body>
</html>
I'm not knee-deep inside socket.io, but IMO the problem is, that the server has no way to know if any listeners are ready.
I think you should emit a 'ready' event, once the return.html is loaded, then listen to 'change_result'. Also separate the socket communication from the POST response on the server. Like so.
server.js
var query;
app.get('/', function(req, res) {
res.sendFile(dir + '/index.html');
});
app.post('/', function(req, res) {
query = req.body.input1;
console.log("Server: In post request.");
console.log(query);
res.sendFile(dir + '/return.html');
});
io.on('connection', function(socket) {
socket.on('ready', function() {
socket.emit('change_result', {result: query});
});
});
return.html
<script>
document.addEventListener('DOMContentLoaded', function() {
var socket = io();
socket.emit('ready', function(data) {});
socket.on('change_result', function(data) {
document.getElementById('heading1').innerHTML = "Result: \""+data.result + "\"";
});
});
</script>

CSS doesn't load into my HTML code using Node.js

I'm trying to add CSS to my HTML using express() function in localhost:3000 by Node.js.
Unfortunately, something is weird. I followed the steps from tutorial step by step but still my css doesn't load. My style.css is in css folder (css/style.css). Here is my code:
app.js (note that I used app and app1)
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var fs = require('fs');
var express = require('express');
var app1 = express();
var mySocket = 0;
app1.use(express.static('/css'));
app.listen(3000); //Which port are we going to listen to?
function handler (req, res) {
fs.readFile(__dirname + '/index.html', //Load and display outputs to the index.html file
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
console.log('Webpage connected'); //Confirmation that the socket has connection to the webpage
mySocket = socket;
});
//UDP server on 41181
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("Broadcasting Message: " + msg); //Display the message coming from the terminal to the command line for debugging
if (mySocket != 0) {
mySocket.emit('field', "" + msg);
mySocket.broadcast.emit('field', "" + msg); //Display the message from the terminal to the webpage
}
});
server.on("listening", function () {
var address = server.address(); //IPAddress of the server
console.log("UDP server listening to " + address.address + ":" + address.port);
});
server.bind(41181);
style.css (css/style.css)
.test
{
color:red;
}
index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" type="text/css" href="/css/style.css" />
</head>
<body>
<script>
var socket = io.connect('http://localhost:3000');
socket.on('field', function (data) {
console.log(data);
$("#field").html(data);
});
</script>
<div class='test'>Data from C#: </div><div id="field"></div>
</body>
</html>
You set the root of the static module to /css here
app1.use(express.static('/css'));
but then you request /css/style.css which means express looks for the file in /css/css/style.css (note that this path is absolute and not relative to your project).
Put everything in a public folder, e.g. public/css/style.css and then
app1.use(express.static(__dirname + '/public'));
Edit: Here's a minimal working example which serves the index.html and the style.css (in public/css/style.css)
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.get('/index.html', function(req, res, next) {
res.sendFile(__dirname + '/index.html');
});
app.listen(3000);

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.

connection refused node js

Helle every body i desired to test sockets,when i'm connected a alert should appear, it work on the computer where Node js is in installed but not in the other computer.
The error :
Failed to load resource: net::ERR_CONNECTION_REFUSED
http://xxx.xxx.xxx.xxx:8080/socket.io/socket.io.js Uncaught
ReferenceError: io is not defined
the code :
server:
var http = require('http');
var fs = require('fs');
var io = require('socket.io');
var server = http.createServer(function(req,res){
res.writeHead(200,{'Content-Type' : 'text/html'});
fs.readFile('./index.html',function(err,content){
res.end(content);
});
}).listen(8080);
io = io.listen(server)
io.sockets.on('connection',function(client){
client.emit('connecte');
});
client :
<html>
<meta charset='utf-8'/>
<head>
<title>my first page</title>
<script src="http://localhost:8080/socket.io/socket.io.js" ></script>
</head>
<body>
<h1>It work</h1>
</body>
<script>
var socket;
socket = io.connect('http://localhost:8080');
socket.on('connecte', function(){
alert('You are connected');
});
</script>
</html>
sorry for the language english is not my first language i try to learn.
Thanks
The Socket.IO docs shows how to use Socket.IO with the built-in http server. Comparing that example and your code you can see you're not using io quite right. Try something like this:
var http = require('http');
var fs = require('fs');
var io = require('socket.io');
var server = http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile('./index.html', function(err, content) {
res.end(content);
});
});
io = io(server);
server.listen(8080);
io.on('connection', function(client) {
client.emit('connected');
});
Also on an unrelated note, you could pipe() the html file to the client instead of buffering the entire file first:
res.writeHead(200, {'Content-Type': 'text/html'});
fs.createReadStream('index.html').pipe(res);

Categories