How to show the node.js output in HTMLPage - node.js

I am using webmatrix and building node.js application.
In that i want to pass the value from the node.js to the HTMLPage in the project.
var http = require('http');
var URL = require('url');
http.createServer(function (req, res)
{
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('Hi man');
}).listen(process.env.PORT || 8080);
With that code i tried it gives a page with hi man.Its obvious.But i want this to be rendered in the html page i am having in the project.
How to achieve tat.
Please give some suggestion on this..

First I recommend you use Expressjs, which is a framework for Nodejs.
Then I recommend you use EJS, an engine template for Nodejs.
When integreses all, you can use code similar to:
...
app.set('views', __dirname + '/views');
app.register('.html', require('ejs'));
app.set('view engine', 'html');
app.use(express.static(__dirname + '/public'));
app.use(express.favicon(__dirname + '/public/img/favicon.ico', { maxAge: 2592000000 }));
app.use(expressValidator);
...
And
...
app.get('/test', function(req, res){
res.render('test', {msg: "Hello World"});
});
...
Finally in your file views/test.html:
...
<div><%- msg %></div>
...
I hope it helps somewhat.
Additionally review:
http://utahjs.com/2010/09/25/nodejs-express-and-ejs-templates/
Render ejs file in node.js
Node.js - EJS example
Greetings.

Sounds like you want to request your nodejs server using AJAX and inject the server's response into an HTML element.
Check out: http://api.jquery.com/jQuery.getJSON/
Here's an example using jQuery to connect and retrieve the server response from node running on port 8080 of different host, and insert that into an HTML element.
node:
var http = require('http');
var url = require('url');
http.createServer(function (req, res)
{
//parse the url and query string from the request
var url_parts = url.parse(req.url, true);
//if the callback query parameter is set, we return the string (or object)
if(url_parts.query.callback){
var str = "Hi man";
res.writeHead(200, {'Content-Type':'text/html'});
res.end(url_parsed.query.callback+'("'+str+'")');
//if it's not set, let's return a 404 error
}else{
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('404 Error');
}
}).listen(process.env.PORT || 8080);
index.html
<div id="my-div"></div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function(){
//getJSON and the callback paramater make us cross-domain capable.
$.getJSON('http://myotherhost.com:8080/?callback=?', function(data){
$("#my-div").html(data);
});
});
</script>

Related

Nodejs post empty object

I simply make a ajax call to certain method in nodeJs app, and expected to log all parameters to see pass data properly. but since I post this its not..
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
// set the port of our application
var port = process.env.PORT || 8080;
app.set('view engine', 'ejs');
// make express look in the public directory for assets (css/js/img)
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
app.get('/', function(req, res) {
// ejs render automatically looks in the views folder
res.render('index');
});
app.listen(port, function() {
console.log('Our app is running on http://localhost:' + port);
});
'use strict';
app.post('/sendMail', function(request, response) {
console.log(request.body)//returns {} but why its empty?
})
and here is ajax call;(I validate paramters exist in headers via dev console)
constructor() {
this.message={
email:"",
message:""
}
}
#action postData() {
$.ajax({
url:"http://localhost:8080/sendMail",
ContentType:'application/json',
dataType:'json',
type:'post',
data:{body:this.message},
success:(result) =>{
},
EDITED: I am able to see data in log if I make a post request via POSTMAN I choose content-type:application/json and added raw json string "{'message':'hello world'}" and I saw in nodejs log its passed successfully whats wrong with my ajax call here ?
It's empty because your using specifying the request should contain a JSON body but don't actually send JSON, your sending an object.
In your ajax request, Change this line
data:{body:this.message}
to
data: JSON.stringify(this.message)

nodejs + express + swig: how do I check the request before rendering?

To be honest, I don't really know how nodejs, express, and swig work.
I have this code that seems to serve up all my html pages
app.engine('html', swig.renderFile);
app.set('view engine', 'html');
app.set('views', __dirname+'/html');
I'd like to be able to examine the request before returning the html file. Specifically, I want to check if the user is using an older version of IE and redirect them to another page instead.
Now, I can examine the request and redirect for specific pages like so
app.get('/veryspecificpage.html', function(req, res) {
if( isBadBrowser(req) ) {
res.writeHead(302, {
'Location': 'browserError.html'
});
res.end();
} else {
res.render('veryspecificpage', {});
});
})
But I don't want to have to specify this for every single .html page. How do I intercept the request and do this for all html pages?
Log each request
Sample node web server. Simply log each request to the server like this...
var http = require('http');
http.createServer(function (req, res) {
console.log(req); // <--- LOGS EACH REQUEST
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
You should use middleware to check every request.
// gets executed for every request to the app
app.use(function (req, res, next) {
// check for browser here and redirect if necessary, if not, next() will continue to other middleware/route.
next();
});
Make sure you place it before any route. You can learn more about it by going to this page.

node.js URL dispatching without hardcoding

I need a corporate website with several pages
I've been able to produce that pages using below codes (using ECT template engine):
var http = require('http');
var url = require('url');
var ECT = require('ect');
var renderer = ECT({ root : __dirname + '/views' });
var data = { title : 'blabla' };
var front = renderer.render('front.ect', data);
var aboutus = renderer.render('aboutus.ect', data);
var ourtechnology = renderer.render('ourtechnology.ect', data);
var anypath = renderer.render('anypath.ect', data);
var server=http.createServer(function(req,res){
var pathname=url.parse(req.url).pathname;
switch(pathname){
case '/':
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(front);
break;
case '/aboutus':
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(aboutus);
break;
case '/ourtechnology':
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(ourtechnology);
break;
default:
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(anypath);
break;
}
}).listen(80);
console.log('Server running');
But above codes are hardcoded.
How to make URL dispatching without hardcoding?
(I need to be able to create the page just like posting blog post)
I prefer MySQL for the database, and need guide where to start
Given your need, you should use express, then the problem becomes:
var express = require('express');
var app = express();
app.get('/', callback_for_root_dir);
app.get('/aboutus', callback_for_aboutus);
app.get('/ourtechnology', callback_for_ourtechnology);
app.get('*', default_callback);
app.listen(80);
Using MySQL for routing would be awkward, because how are you going to define the corresponding callbacks with a new path? You still need to code the callback in Node.js and restart the app, so there is no much point using MySQL data for routing. Besides, you can use powerful regular expressions for paths with Express.
You can also use a library to extend express normal routing, and soft-code your routes even
more.
https://github.com/hrajchert/express-shared-routes

Node.js, Express, Jade - Error: Can't set headers after they are sent

I'm getting the following error when trying to produce an HTML page using Jade. Has anybody else experienced this issue. I noted below where exactly the error is caused.
Error
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:644:11)
at ServerResponse.res.setHeader (/Users/dereklo/node_modules/express/node_modules/connect/lib/patch.js:59:22)
at ServerResponse.res.set.res.header (/Users/dereklo/node_modules/express/lib/response.js:475:10)
at ServerResponse.res.contentType.res.type (/Users/dereklo/node_modules/express/lib/response.js:350:15)
at ServerResponse.res.send (/Users/dereklo/node_modules/express/lib/response.js:111:14)
at res.render.fn (/Users/dereklo/node_modules/express/lib/response.js:672:10)
at Object.exports.render (/Users/dereklo/node_modules/jade/lib/jade.js:216:5)
Node.js/Express/Jade Source Code
var http = require('http'),
express = require('express'),
jade = require('jade'),
url = require('url'),
jsdom = require('jsdom'),
child_proc = require('child_process'),
w,
h,
scripts = ["/Users/dereklo/Node/pie/d3.min.js",
"/Users/dereklo/Node/pie/d3.v2.js",
"/Users/dereklo/Node/pie/d3.layout.min.js",
"/Users/dereklo/Node/pie/RadialScriptMobileServ.js",
"/Users/dereklo/Node/pie/RadialScriptMobile.js",
"/Users/dereklo/Node/pie/canvg.js"];
//scripts = ["./d3.v2.js",
// "./d3.layout.min.js",
// "./pie.js"]
htmlStub = '<!DOCTYPE html><div id="RadialScriptMobileServ"></div>',
querystring = require("querystring"),
fs = require("fs"),
formidable = require("formidable"),
path = require('path'),
request = require('request')
svgsrc = '';
//create an app server
var app = require('express').createServer();
//set path to the views (template) directory
app.set('views', __dirname + '/views');
//set path to static files
app.use(express.static(__dirname + '/../public'));
//handle GET requests on /
app.get('/', function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
w = (url.parse(req.url, true).query['width']);
h = (url.parse(req.url, true).query['height']);
console.log("width: ",w);
console.log("height: ",h);
request("http://dcaps-staging.media.mit.edu:8080/api/reality_analysis_service/get_reality_analysis_data?document_key=radialData&bearer_token=8e2f9e3129", function (err, result, json) {
json = JSON.parse(json);
console.log("my radial data: ",json.radialData.data);
jsdom.env({features:{QuerySelector:true}, html:htmlStub, scripts:scripts, done:function(errors, window) {
svgsrc = window.insertRadial("#RadialScriptMobileServ",w,h,json).innerHTML;
console.log(svgsrc);
res.render('/Users/dereklo/Node/pie/Jade_radial.jade', {pageTitle: 'Franz Enzenhofer'}); // ERROR OCCURRING HERE!
// res.write(svgsrc);
res.end();
}})
})
});
//listen on localhost:3000
app.listen(3000);
//console.log('Pie SVG server running at http://127.0.0.1:3000/');
My issue was that I needed to remove:
res.writeHead(200, {'Content-Type': 'text/plain'});
It now works perfectly. I hope this will help others who stumble upon this post...
You can do it two ways. Either add another route above your app.get(/ ..) like this:
// global controller
app.get('/*',function(req,res,next){
res.header('Content-Type': 'text/plain' , 0 );
next(); // http://expressjs.com/guide.html#passing-route control
});
Or you can add middle ware function to your existing route
addToHeader = function (req, res, next) {
console.log("add to header called ... " + req.url);
res.header('Content-Type': 'text/plain', '0');
next();
}
and then change your routes to sth like this:
app.get('/', addToHeader, function(req,res){
var stuff = { 'title': 'blah' };
res.render('mytemplate',stuff);
});
When using res.render(), you don't need to handle response manually (res.end(), res.writeHead(), etc.).

How does Node.js render views?

In a basic Node.js application with a single app.js file and one index.html document where in app.js the following is specified, then firing up a server and visiting localhost:8080 works just fine:
server = http.createServer( function(req, res) {
fs.readFile('index.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
fs.readFile('new.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
});
server.listen(8080);
However, when duplicating index.html to another file like new.html and editing certain content, then adding an link into index.html linking to the new page, clicking on the link will render the same content as in index.html. In fact, linking to any non-existent html page will append the subsequent page to the URL but keep showing index.html's contents.
Following a suggestion of rewriting the fs.readFile line to be:
fs.readFile(req.url, function(err, page) { ...
Then going to localhost:8080 loads new.html's contents for some reason I don't understand. How should one render out these views?
Following on the other answers given and also recommending express. But first, the short answer to the question "how does node.js render views?" is: it doesn't.
When you build a node application you are building a small web server, using the minimal building blocks node gives you like http.createServer(). It's up to you to write the logic to choose what to send in response to a request.
Or you can use an existing framework like Express. Here is the solution using express:
Install express:
npm install express
Then, in your app.js:
var express = require('express');
var app = express.createServer();
app.get('/index.html', function(req,res) {
res.render('index.html');
});
app.get('/new.html', function(req,res) {
res.render('new.html');
});
app.listen(8080)
You can also use EJS or Jade as the template language by adding this before the createServer line:
app.set('view engine', 'ejs');
or:
app.set('view engine', 'jade');
Because you need to have conditions on your request access url (req.url).
Right now it closes the response on your first res.end() regardless of your url, and never reach the rest of your code (well it does but the response already fired before so it has no effect).
try this:
server = http.createServer( function(req, res) {
if (req.url == '/index.html') { //will be executed only on index.html
fs.readFile('index.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
}
if (req.url == '/new.html') { //will be executed only for new.html
fs.readFile('new.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
}
});
server.listen(8080);

Resources