node.Js - how run different pages? - node.js

so when enter the url: http://mysite.com/ there will be loading the server.js file (the index file). I want load the account.js when I enter url http://mysite.com/account.
How to do that?

In server.js , on top include account.js >
var account = require("./account");
In your createServer function in nodejs, you check if the URI is /account >
//Create Server
http.createServer(function (request, response) {
// Parse the entire URI to get just the pathname
var uri = url.parse(request.url).pathname, query;
if (uri == "/account") //If it's mysite.com/account
{
request.setEncoding("utf8");
request.content = '';
//call account.whatever() to route to your account functionality
//send the response from it
}
else if (uri == "/") //It's mysite.com
{
//call whatever you have in the current server.js
}
}).listen(8080);

Nodejs is a daemon. It doesn't load scripts every time you making request.
You can use something like that:
var severs = require('server.js'),
accounts = require('accounts.js');
require('http').createServer(function (req, res) {
var path = require('url').parse(req.url).pathname;
res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
if (path == '/account') {
res.end(accounts.run());
} else {
res.end(severs.run());
}
}).listen(80);

It is better to use request routers - see connect and express NPM modules. Manual path comparison does not scale - it will turn your code into nightmare as you add more and more URLs.
For a standalone router, see clutch NPM module, but router inside connect is more mature and can be used in a standalone way. express is an extension of connect, so it uses the router from connect.

Related

How to show health status of node server on HTML

I have two servers. One is server1 running on port 8080 and another one is main app server which is running on 8081. Now i want to showcase the health status of server1 on UI(HTML) which is running on main app server(8081).I want to display the these elements on HTML.
1.Status code of server one.
2.Server is UP Or Down.
3.Response of the server one.
This is my nodejs code.
const express = require('express');
const http = require('http');
const fs = require('fs');
const bodyParser = require('body-parser');
const router = express.Router();
const path = require('path');
const ejs = require('ejs');
const app = express();
const server1 = express();
server1.get('/health', function (req, res, next) {
res.json({health: true});
res.status(200).end();
});
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.get('/', (req,res) => {
res.render('index');
console.log('server two')
})
server1.listen(8080);
app.listen(8081);
Ajax part:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
document.getElementById("#demo1").innerHTML = xmlhttp.responseText;
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
}
else {
document.getElementById('demo1').innerHTML = 'something else other than 200 was returned';
}
}
};
xmlhttp.open("GET", "http://localhost:8080/health", true);
xmlhttp.send();
HTML:
<div id="demo1"></div>
What should i exactly do to display the health status of server1 on UI.
I've wrote and published a Node App with a React front-end that does exactly this. It's purely open source and free to use.
It allows you to define a list of websites, webapps, API endpoints and servers to monitor in JSON.
The React front-end provides a dashboard showing state of each asset. The backend will periodically call each 'asset' in your list and record state and response time and also broadcast the results to any connected client via Sockets.io.
Feel free to install as an NPM package, or go onto GitHub and clone the repo.
I understand you might not want an out of the box solution, so feel free to take a look at my code to help you in building your own solution.
NPM Link
GIT HUB Link
Running example on Heroku
You could create a specific route that will be called on a specific setInterval() by your front-end javascript. This route could return a JSON with an errors array if there are any. Something along the lines of:
app.get('/health-check', (req,res) => {
// check database connectivity and any other staff you want here
// add any errors in an array
if (errors.length > 0) {
return res.status(500).json({health: false, errors: errors});
}
return res.status(200).send({health: true});
});
Be careful as there may exist errors that you don't want to show to your user. This will depend on the type of application etc.
Then make an AJAX call from your front-end JS code within a setInterval() function. The implementation of this will depend of the library/framework you use if you do but using jquery for example would be like:
const healthTimer = setInterval(() => {
$.ajax({
url: "[your server url]/health-check",
type: "GET",
success: function(xml, textStatus, xhr) {
// get the server status here if everything is ok
$('div.server-health span.success').text(`Server Status: ${xhr.status}`);
$('div.server-health span.error').text('');
console.log('RESPONSE CODE:', xhr.status);
},
error: function (request, status, error) {
// handle the error rendering here
$('div.server-health span.error').text(`Server Status: ${status}`);
$('div.server-health span.success').text('');
alert(request.responseText);
}
});
}, 15000); // send the request every 15 seconds
Inside your html file you can have a <div> to show the server health:
<div class="server-health">
<span class="error"></span>
<span class="success"></span>
</div>

custom mini router in node.js

I've to implement a custom mini router and have been looking at express js for inspirations.
Can anyone guide me on express js creates route handlers under the hood.
For instance, how the following can be implemented?
Node server code
http.createServer(function (req, res) { //how routing is done after?
//req???
req.get("/customers", function(){})
req.get("/customers/:id", function(){})
}).listen(9615);
is express js using regular expressions? Please also point to the right script in the github repository.
You need to check this https://github.com/expressjs/express/blob/master/lib/router/index.js. This is a separate module of expressjs for routing and you can pluck it out for your personal use without reinventing the wheel all over.
[EDIT] - To give idea how it might be done.
var routes = [];
var app = {};
app.get = function(pattern, cb) {
var splits = pattern.split("/");
var route = "";
var regex = "";
for(i=0; i < splits.length; i++) {
if (splits[i].indexOf(':') === -1) {
route += splits[i]+"/";
} else {
regex = splits[i].replace(":", "");
}
}
routes.push({ route : routes, regex : regex, cb: cb });
}
app.get("/customers", callback);
.
.
.
// handle incoming request. requestPath comes from server
var requestPath = "/customers"; // example only.
app.handleRequest(requestPath) {
for(i = 0; i < routes.length; i++) {
if(routes[i].route === requestPath) {
cb = routes[i].cb;
}
}
cb();
}
Kudos to robertklep.
Under the hood express js uses path-to-regexp.
I also found the regular expression from their page that is used by express js to parse the URL link
/^(?:\/(?=$))?$/i
There's not much re-inventing the wheel involved in here when all I wanted is a basic router without getting the whole framework and all of it's dependencies in my project.
Please take a look at the Express JS documentation. It would be pretty much it. For example, a piece of code using Express JS:
// GET method route
app.get('/', function (req, res) {
res.send('GET request to the homepage');
});
// POST method route
app.post('/', function (req, res) {
res.send('POST request to the homepage');
});
As for regular expressions, yes, you can use them. For example:
app.get('/ab(cd)?e', function(req, res) {
res.send('ab(cd)?e');
});
Besides that, please take look at one example in the Express JS GitHub repository.
As for the Router implementation in Express JS, look at their GitHub code (router script).

How to forward a request to other endpoint in node.js

In my scenario I need forward get request to another end point. In my machine there are two servers php and node.js server. Node.js is like a "man in the middle", PHP server must work in the same way.
Node.js server code
var express = require('express');
var fs = require('fs');
var path = require('path');
var http = require('http');
var https = require('https');
var app = express();
var HTTP_PORT = 3000;
// Create an HTTP service
http.createServer(app).listen(HTTP_PORT,function() {
console.log('Listening HTTP on port ' + HTTP_PORT);
});
//endpoint for tracking
app.get('/track', function(req, res) {
sendRequestToOtherEndPoint(req);
processRequest(req);
res.setHeader('Content-Type', 'application/json');
res.send('Req OK');
});
function processRequest(req){
console.log("request processed");
}
function sendRequestToOtherEndPoint(req){
//magic here :)
}
When this server receive a get request in port 3000, it process request information and it must forward the same requesto to another end point.
For example:
Get localhost:3000/track?param1=1&param2=2
Server process get request
Server forward get request to localhost/final-endpoint?param1=1&param2=2
Depending on what you're trying to do, you can create a new request to the end-point:
//endpoint for tracking
app.get('/track', function(req, res) {
req.get({url: 'http://end-point', headers: req.headers});
processRequest(req);
res.setHeader('Content-Type', 'application/json');
res.send('Req OK');
});
More info: https://github.com/request/request
There are a couple of useful libraries that one could use:
http-proxy-middleware:
const proxy = require('http-proxy-middleware')
var apiProxy = proxy('/track', {target: 'http://end-point'});
app.use(apiProxy)
axios-express-proxy
import express from 'express';
import { Proxy } from 'axios-express-proxy';
const app = express();
const port = 3000;
app.get('/track', (req, res) => Proxy('http://end-point', req, res));
In you case res.redirect might help.
app.get('/track', function(req, res) {
// process the request
// then redirect
res.redirect('/final-endpoint');
});
Then catch the redirected request in final endpont.
app.get('/final-endpoint', function(req, res) {
// proceess redirected request here.
});
See the Express docs
If your second endpoint is on a different server, (e.g. PHP) then you're going to need to either redirect the client (as in sohel's answer), or spoof a request from Node to the PHP server and then send the response back to the client. This latter option is definitely non-trivial so I would question whether it's crucial not to use a client redirect.
If you're talking about two express endpoints, then I think the simplest answer might be not to actually forward at all, but just use the endpoint callback directly instead:
app.get('/track', trackCallback);
app.get('/otherendpoint', otherendpointCallback);
function otherendpointCallback(req, res) {
// do your thing
}
function trackCallback(req, res) {
otherendpointCallback(req, res);
processRequest(req);
res.setHeader('Content-Type', 'application/json');
res.send('Req OK');
};
Depending on exactly what you want to do at the other end point, you might need to spoof some of req's fields (e.g. req.url)

proxying requests from a secure application

im trying to proxy requests from a secure web application(https) in node (its an internal application) and im not quite sure how to do it...
the below is my code which works when i try it from an non secured app (http).
It just strips out a page name and uses it in another app. I read the docs but still not sure how to do it. Do i need to have the ssl info from my application for this to work?
var http = require('http');
var httpProxy = require('http-proxy');
var request = require('request');
var app = require('express.io')();
app.http().io();
//
// Create proxy server
//
var proxy = httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(9085);
// Send the client html.
app.get('/', function(req, res) {
res.sendfile(__dirname + '/client1.html');
})
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong!');
});
app.all('/Domain/*', function(req, res) {
console.log(req.url);
if (req.url.indexOf("Page.do") > -1) {
// URL to Atlas
var otherAppURL = "http://myotherapp/pages/";
var temp = req.url.split("Page.do")[0].split("/");
var pageName = temp[temp.length - 1];;
app.io.broadcast('update', {
url: atlasURL + pageName + '.html'
});
};
// This doesnt work
//var url = "https://mysecureapp:9044" + req.url;
// This works
var url = "http://localhost:9080" + req.url;
req.pipe(request(url)).pipe(res);
})
app.listen(9000);
Yes, you do need an SSL Certificate for an HTTPS connection. According to the website https://www.globalsign.com/en/ssl-information-center/what-is-an-ssl-certificate/ :
The standard HTTP is changed to HTTPS, automatically telling the browser that the connection between the server and the browser must be secured using SSL.
This means that with an HTTPS connection, you need to have the server secured with SSL.
For connecting with HTTPS in Node, this website might help you:
http://gaboesquivel.com/blog/2014/nodejs-https-and-ssl-certificate-for-development/
Ok i might be mistaking but this line doesn't make sense ,
req.pipe(request(url)).pipe(res);
by the time the route handler hits, the req object is ready
so req.pipe has no meaning.
please check that url returns a valid response
request(url).pipe(res); should work
http / https is not an issue

How to proxy to root path with node http-proxy

I am trying to setup a proxy with an express app to a root path from a specific path in my application:
http://my-domain.com/some/route --> http://another-domain:8000/
I have tried multiple things per the http-proxy docs but I keep hitting a wall with the paths/routing. I am trying to do this within a logged in express app so that I can utilize my authentication behind the app i'm trying to proxy too. I keep getting an error with the proxy'd app saying the path '/some/route' is not defined...etc.
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
proxy.proxyRequest(req, res, {
host:'localhost',
port:8000
});
I've also tried:
var url = 'http://localhost:8000/';
var httpProxy = require('http-proxy'),
proxy = httpProxy.createProxyServer({});
proxy.web(req,res, { target: url }, function(e) {
console.log('proxy.web callback');
console.log(e);
});
The function calls but I end up with an express 404 error...
I would also like to pass in some variables if that is possible so for example:
http://my-domain.com/some/route?var1=something&var2=something --> http://another-domain:8000/?var1=something&var2=something
But could not figure out if that was possible, I tried setting it on the request since that was being sent into the proxyRequest, but was unable to find them in the second application.
No, you can't do this with just node-http-proxy.
But it's possible with http-proxy-middleware (and you likely use it already):
From comment by #chimurai on github:
You can rewrite paths with the pathRewrite option.
var options = {
target: 'http://test.com',
changeOrigin: true,
pathRewrite: {'^/api' : ''} // <-- this will remove the /api prefix
};
server.middleware = proxyMiddleware('/api', options);
And if you come here because you're using webpack-dev-server, note that it also internally uses http-proxy-middleware, starting from version 2.0.0-beta (see PR).
Side note: There is also a node-proxy plugin, http-proxy-rules, so you can use this one if you don't want middleware.
Well, I encounter another problem, but needed to solve this problem first. I came up with this code, which worked fine for me ;)
Just use this for "/some/route"
.... // your stuff
httpProxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('some error');
});
app.all( '/some/route/*' , function( req , res ) {
var url = req.url;
url = url.slice(11); // to remove "/some/route"
req.url = url;
return httpProxy.web(req, res , { target: "http://another-domain:8000" } );
} );
hope this helps.

Resources