Unit-2 Node JS
Unit-2 Node JS
js)
Working with JSON, Using the Buffer Module to Buffer Data, Using the Stream
Module to Stream Data, Accessing the File System from Node.js- Opening,
Closing, Writing, Reading Files and other File System Tasks. Implementing
HTTP Services in Node.js- Processing URLs, Processing Query Strings and
Form Parameters, Understanding Request, Response, and Server Objects,
Implementing HTTP Clients and Servers in Node.js, Implementing HTTPS
Servers and Clients. Using Additional Node.js Modules-Using the os Module,
Using the util Module, Using the dns Module, Using the crypto Module.
Accessing the File System from Node.js
• Interacting with the file system in Node.js is important especially if you need to manage
dynamic files to support a web application or service.
• Node.js provides a good interface for interacting with the file system in the fs module. This
module provides the standard file access APIs that are available in most languages to open,
read, write, and interact with files
• To include the File System module, use the require() method:
• var fs = require('fs’);
• Common use for the File System module:
• Read files
• Create files
• Update files
• Delete files
• Rename files
read.js
// The fs.readFile() method is used to read files on your
computer
var fs = require('fs');
var data=fs.readFileSync('file1.txt');
file1.html
<html>
<body>
<h1>My Header</h1>
<p>My paragraph.</p>
</body>
</html>
read.js
// The fs.readFile() method is used to read files on your computer
var http = require('http');
var fs = require('fs');
http.createServer(function (req, res) {
fs.readFile('file1.html', function(err, data) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
return res.end();
});
}).listen(8080);
Write Files
//The fs.writeFile() method replaces the specified file and
content:
//Example:Replace the content of the file "file3.txt":
var fs = require('fs');
fs.writeFile('file3.txt', 'This is my text', function (err) {
if (err) throw err;
console.log('Replaced!');
});
APPEND FILES
//The fs.appendFile() method appends specified content to
a file.
//If the file does not exist, the file will be created:
var fs = require('fs');
fs.appendFile('file1.txt', ‘FULL STACK DEVELOPMENT',
function (err) {
if (err) throw err;
console.log('Saved!');
});
Delete Files
//To delete a file with the File System module, use the
fs.unlink() method.
//Delete "file2.txt":
var fs = require('fs');
fs.unlink('file2.txt', function (err) {
if (err) throw err;
console.log('File deleted!');
});
Rename files
//To rename a file with the File System module, use the
fs.rename() //method. Rename "file1.txt" to
"renamedfile.txt":
var fs = require('fs');
fs.rename('file1.txt', 'renamedfile.txt', function (err) {
if (err) throw err;
console.log('File Renamed!');
});
Synchronous Versus Asynchronous
Synchronous Versus Asynchronous File System Calls:
• The fs module provided in Node.js makes almost all functionality available in
two forms: asynchronous and synchronous.
• Synchronous file system calls block until the call completes and then control is
released back to the thread. This has advantages but can also cause severe
performance issues in Node.js if synchronous calls block the main event thread
or too many of the background thread pool threads. Therefore, synchronous file
system calls should be limited in use when possible.
• Asynchronous calls are placed on the event queue to be run later. This allows
the calls to fit into the Node.js event model; however, this can be tricky when
executing your code because the calling thread continues to run before the
asynchronous call gets picked up by the event loop
Synchronous Versus Asynchronous
Important differences between synchronous and asynchronous file system calls in
Node.js:
■ Asynchronous calls require a callback function as an extra parameter. The callback
function is executed when the file system request completes, and typically contains an
error as its first parameter.
■ Exceptions are automatically handled by asynchronous calls, and an error object is
passed as the first parameter if an exception occurs. Exceptions in synchronous calls
must be handled by your own try/catch blocks of code.
■ Synchronous calls are run immediately, and execution does not return to the current
thread until they are complete. Asynchronous calls are placed on the event queue, and
execution returns to the running thread code, but the actual call will not execute until
picked up by the event loop.
Opening and Closing Files
r+ Open file for reading and writing. An exception occurs if the file does not exist.
rs+ Same as rs except the file is open file for reading and writing
w Open file for writing. The file is created if it does not exist or truncated if it does
exist.
wx Same as w but fails if the path exists.
w+ Open file for reading and writing. The file is created if it does not exist or truncated if
it exists.
wx+ Same as w+ but fails if path exists
a Open file for appending. The file is created if it does not exist.
a+ Open file for reading and appending. The file is created if it does not exist.
•In Node.js, Modules are the blocks of encapsulated code that communicate with an external
application on the basis of their related functionality.
•Modules can be a single file or a collection of multiple files/folders.
•The reason programmers are heavily reliant on modules is because of their reusability as well
as the ability to break down a complex piece of code into manageable chunks.
• Different types of Node.js Modules:
Core Modules/ Built-in
Local Modules
Third-party modules
Core Modules(BUILT-IN)
•Node.js has many built-in modules that are part of the platform and come with Node.js installation. These modules
can be loaded into the program by using the required function.
•Syntax: const module = require('module_name');
•The require() function will return a JavaScript type depending on what the particular module returns.
const http = require('http’);
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('Welcome to this page!');
res.end();
}).listen(3000);
• In the above example, the require() function returns an object because the Http module returns its functionality as
an object. The function http.createServer() method will be executed when someone tries to access the computer
on port 3000. The res.writeHead() method is the status code where 200 means it is OK, while the second
argument is an object containing the response headers.
Core Modules
process provides information and control about the current Node.js process.
querystring utility used for parsing and formatting URL query strings.
tmpdir() - Returns a string path to the default temp directory for the OS. Useful if you
need to store files temporarily and then remove them later.
endianness()-Returns BE or LE for big endian or little endian, depending on the architecture
of the machine.
hostname()- Returns the hostname defined for the machine. This is useful when
implementing network services that require a hostname.
type() - Returns the OS type as a string
platform() Returns the platform as a string; for example, win32, linux, or freeBSD.
arch() Returns the platform architecture; for example, x86 or x64.
release() Returns the OS version release.
uptime() Returns a timestamp in seconds of how long the OS has been running.
The os module
cpus() Returns an array of objects that describes the model, speed, and times.
This array contains the amount of time the CPU has spent in user, nice,
sys, idle, and irq.
networkInterfaces() Returns an array of objects describing the address and family of
addresses bound on each network interface in your system.
EOL Contains the appropriate End Of Line characters for the operating system; for
example, \n or \r\n. This can be useful to make your application cross-platform
compatible when processing string data.
The os module
//Demonstrate OS MODULE functions
var os = require('os');
console.log("tmpdir :\t" + os.tmpdir());
console.log("endianness :\t" + os.endianness());
console.log("hostname :\t" + os.hostname());
console.log("type :\t\t" + os.type());
console.log("platform :\t" + os.platform());
console.log("arch :\t\t" + os.arch());
console.log("release :\t" + os.release());
console.log("uptime :\t" + os.uptime());
console.log("loadavg :\t" + os.loadavg());
console.log("totalmem :\t" + os.totalmem());
console.log("freemem :\t" + os.freemem());
console.log("EOL :\t" + os.EOL);
console.log("cpus :\t\t" + JSON.stringify(os.cpus()));
console.log("networkInterfaces : " + JSON.stringify(os.networkInterfaces()));
• tmpdir : C:\Users\91966\AppData\Local\Temp
• endianness : LE
• hostname : DESKTOP-N5NOQHC
• type : Windows_NT
• platform : win32
• arch : x64
• release : 10.0.22621
• uptime : 207517.671
• loadavg : 0,0,0
• totalmem : 8430252032
• freemem : 851951616
• EOL :
• cpus : [{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1352843,"nice":0,"sys":560953,"idle":20264609,"irq":41109}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1688953,"nice":0,"sys":356250,"idle":20132984,"irq":10125}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1836437,"nice":0,"sys":521140,"idle":19820671,"irq":11046}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":2336656,"nice":0,"sys":376593,"idle":19464968,"irq":7390}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1557625,"nice":0,"sys":493812,"idle":20126796,"irq":11890}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1244921,"nice":0,"sys":335031,"idle":20598281,"irq":7468}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1273156,"nice":0,"sys":454500,"idle":20450578,"irq":10781}},{"model":"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz","speed":2112,"times":
{"user":1351343,"nice":0,"sys":397312,"idle":20429578,"irq":7640}}]
• networkInterfaces : {"VMware Network Adapter VMnet1":
[{"address":"fe80::16ab:dd25:1c82:58d4","netmask":"ffff:ffff:ffff:ffff::","family":"IPv6","mac":"00:50:56:c0:00:01","internal":false,"cidr":"fe80::16ab:dd2
5:1c82:58d4/64","scopeid":8},
{"address":"192.168.111.1","netmask":"255.255.255.0","family":"IPv4","mac":"00:50:56:c0:00:01","internal":false,"cidr":"192.168.111.1/24"}],"VMwar
e Network Adapter VMnet8":
[{"address":"fe80::6a49:dc4:e71d:73a9","netmask":"ffff:ffff:ffff:ffff::","family":"IPv6","mac":"00:50:56:c0:00:08","internal":false,"cidr":"fe80::6a49:dc4:e
71d:73a9/64","scopeid":14},
{"address":"192.168.204.1","netmask":"255.255.255.0","family":"IPv4","mac":"00:50:56:c0:00:08","internal":false,"cidr":"192.168.204.1/24"}],"Wi-Fi":
[{"address":"fe80::8c10:d740:d138:2f86","netmask":"ffff:ffff:ffff:ffff::","family":"IPv6","mac":"6c:6a:77:8c:65:04","internal":false,"cidr":"fe80::8c10:d740
:d138:2f86/64","scopeid":21},
{"address":"192.168.0.102","netmask":"255.255.255.0","family":"IPv4","mac":"6c:6a:77:8c:65:04","internal":false,"cidr":"192.168.0.102/24"}],"Loopba
Using the util Module
The util module in Node.js provides utility functions that help with debugging,
formatting, and working with objects and types.
The util module is a catch-all module that provides functions for
• formatting strings,
• converting objects to strings,
• checking object types,
• performing synchronous writes to output streams,
• and some object inheritance enhancements.
Syntax:
const util = require('util');
Formatting Strings
The util.format() function accepts a formatter string as the first argument and returns a
formatted string.
util.format(format[...args])
The format argument is a string that can contain zero or more placeholders.
Each placeholder begins with a % character and is replaced with the converted string value
from its corresponding argument.
The first formatter placeholder represents the second argument and so on. The following is a list
of supported placeholders:
■ %s: Specifies a string
■ %d: Specifies a number (can be integer or float)
■ %i: Specifies an integer
■ %f: Specifies a floating point value
■ %j: Specifies a JSON stringifyable object
■ %: If left empty afterward, does not act as a placeholder
Formatting Strings
The following is a list of things to keep in mind when using format():
■ When there are not as many arguments as placeholders, the placeholder is not
replaced. For example:
util.format('%s = %s', 'Item1’); // 'Item1:%s'
■ When there are more arguments than placeholders, the extra arguments are
converted to strings and concatenated with a space delimiter.
util.format('%s = %s', 'Item1', 'Item2', 'Item3'); // 'Item1 = Item2 Item3'
■ If the first argument is not a format string, then util.format() converts each
argument to a string, concatenates them together using a space delimiter, and then
returns the concatenated string. For example:
util.format(1, 2, 3); // '1 2 3'
Checking Object Types
• It is often useful to determine whether an object you have received back from a
command is of a certain type.
• To do this, you can use the instanceof operator, which compares the object types and
returns true or false.
• For example:
• ([1,2,3] instanceof Array) //true
Formatting Strings & checking Object types
var util=require('util')
console.log(util.format('%s = %s', 'Item1'));
console.log(util.format('%s = %s', 'Item1', 'Item2',
'Item3'));
console.log(util.format(1,2,3));
console.log(([1,2,3] instanceof Array));
Output:
Item1 = %s
Item1 = Item2 Item3
1 2 3
true
Converting JavaScript Objects to Strings
• Especially when debugging, you need to convert a JavaScript object to a
string representation.
• The util.inspect() method allows you to inspect an object and then return a
string representation of the object.
• The following shows the syntax for the inspect() method:
• util.inspect(object, [options])
• The object parameter is the JavaScript object you want to convert to a string.
• The options method allows you to control certain aspects of the formatting
process.
Converting JavaScript Objects to Strings
options can contain the following properties:
■ showHidden: When set to true, the non-enumerable properties of the
object are also converted to the string. Defaults to false.
■ depth: Limits the number of levels deep the inspect process traverses
while formatting properties that are also objects. This can prevent infinite loops .
Defaults to 2; if it is null, it can recurse forever.
■ colors: When set to true, the output is styled with ANSI color codes.
Defaults to false.
■ customInspect: When set to false, any custom inspect() functions defined on
the objects being inspected are not called. Defaults to true.
Converting JavaScript Objects to Strings
var obj = { first:'Caleb', last:'Dayley' };
obj.inspect = function(depth) {
return '{ name: "' + this.first + " " + this.last + '" }';
};
console.log(util.inspect(obj));
//Outputs:
{ first: 'Caleb', last: 'Dayley', inspect: [Function (anonymous)] }
{ name: "Caleb Dayley" }
Inheriting Functionality from Other Objects
The util module provides the util.inherits() method to allow you to
create objects that inherit the prototype methods from another.
When you create the new object, the prototype methods are
automatically used.
The following shows the format of the util.inherits() method:
util.inherits(constructor, superConstructor)
The prototype of constructor is set to the prototype of
superConstructor and executed when a new object is created.
You can access the superConstructor from your custom object
constructor using the constructor.super_ property
Using the dns Module
Using the dns Module
• The dns module in Node.js provides functionalities for domain name
resolution. It allows you to perform DNS lookups, or do reverse lookups,
resolve hostnames, and interact with DNS records
• A DNS lookup contacts the domain name server and requests records
about a specific domain name.
• A reverse lookup contacts the domain name server and requests the DNS
name associated with an IP address.
• The dns module provides functionality for most of the lookups that you
may need to perform.
• Syntax:
• const dns = require('dns');
Methods that can be called on the dns Module
Event Description
lookup(domain, [family], callback) Resolves the domain. The family attribute can be 4, 6, or null,
where 4 resolves into the first found A (IPv4) record, 6 resolves
into the first round AAAA (IPv6) record, and null resolves both.
The default is null.
resolve(domain, [rrtype], callback) Resolves the domain into an array of record types specified by
rrtype.
rrtype can be ■ A: IPV4 addresses, the default ■ AAAA: IPV6
addresses ■ MX: Mail eXchange records ■ TXT: Text records ■
SRV: SRV records ■ PTR: Reverse IP lookups ■ NS: Name
Server records ■ CNAME: Canonical Name records
reverse(ip, callback) Does a reverse lookup on the ip address. The callback function
receives an error object if one occurs and an array of domains if
the lookup is successful.
Methods that can be called on the dns
//Performing lookups and then reverse lookups on domains and IP addresses
Module
var dns = require('dns');
console.log("Resolving www.google.com . . .");
dns.resolve4('www.google.com', function (err, addresses) {
console.log('IPv4 addresses: ' + JSON.stringify(addresses, false, ' '));
addresses.forEach(function (addr) {
dns.reverse(addr, function (err, domains) {
console.log('Reverse for ' + addr + ': ' + JSON.stringify(domains));
});
});
});
Output:
Resolving www.google.com . . .
IPv4 addresses: [
"172.217.163.196"
]
Reverse for 172.217.163.196: ["maa05s06-in-f4.1e100.net"]
Using the crypto Module
The crypto module in Node.js provides cryptographic functionality, including encryption,
decryption, hashing, and key generation.
It supports various cryptographic algorithms like AES, RSA, SHA, and HMAC.
It creates cryptographic information, or in other words, creates secure communication using
secret code. The easiest way to do ensure crypto is loaded is to use a simple try catch (err);
for example:
let crypto;
try {
crypto = require('crypto');
} catch (err) {
console.log('crypto support is disabled!');
}
The crypto module includes several classes that provide functionality to encrypt and decrypt
data and streams.
Classes that can be used in the crypto module
Class description
certificate Used for working with SPKAC (a certificate signing request mechanism) and primarily
used to handle output of HTML5.
cipher Used to encrypt data in either a stream that is both readable and writable, or using the
cipher.update and cipher.final methods
decipher The opposite of cipher. Used to decrypt data using either a readable and writable
stream or the decipher.update and deciper.final methods
diffieHellman Used to create key exchanges for Diffie-Hellman (a specific method for exchanging
cryptographic keys)
hash Used to create hash digests of data using a readable and writable stream or hash.update
and hash.digest
sign Used to generate signatures.
Output:
Encrypted Password
0ebc7d846519b955332681c75c834d50
Decrypted Password
BadWolf
Implementing HTTP Services in Node.js
• One of the most important aspects of Node.js is the ability to quickly implement
HTTP and HTTPS servers and services.
• Node.js provides the http and https modules, and they provide the basic
framework to do most everything you need from an HTTP and HTTPS
standpoint.
• In fact, it is not difficult to implement a full webserver using just the http
module.
• We will likely use a different module, such as express, to implement a full-on
webserver.
• This is because the http module is pretty low level. It doesn’t provide calls to
handle routing, cookies, caching, and so on.
• You can create basic HTTP servers that provide an interface for communications
behind your firewall and then basic HTTP clients that interact with those
services.
Processing URLs
• The Uniform Resource Locator (URL) acts as an address label for the HTTP
server to handle requests from the client.
• It provides all the information needed to get the request to the connect server on
a specific port and access the proper data.
• The URL can be broken down into several different components, each providing
a basic piece of information for the webserver on how to route and handle the
HTTP request from the client.
• Figure illustrates the basic structure of a URL and the components that may be
included.
Properties of the URL object
Property Description
href This is the full URL string that was originally parsed.
protocol The request protocol lowercased
host The full host portion of the URL including port information lowercased.
auth The authentication information portion of a URL.
hostname The hostname portion of the host lowercased.
port The port number portion of the host
pathname The path portion of the URL including the initial slash if present
search The query string portion of the URL including the leading question mark
path The full path including the pathname and search.
query This is either the parameter portion of the query string or a parsed object containing the query string
parameters and values if the parseQueryString is set to true
hash The hash portion of the URL including the pound sign (#).
Understanding the URL Object
• To use the URL information more effectively, Node.js provides the url module that
provides functionality to convert the URL string into a URL object.
• To create a URL object from the URL string, pass the URL string as the first
parameter to the following method:
• url.parse(urlStr, [parseQueryString], [slashesDenoteHost])
• The url.parse() method takes the URL string as the first parameter.
• The parseQueryString parameter is a Boolean that when true also parses the query
string portion of the URL into an object literal. The default is false.
• The slashesDenoteHost is also a Boolean that when true parses a URL with the format
of //host/path to {host: 'host', pathname: '/path'} instead of {pathname:
'//host/path'}. The default is false.
Output:
urlObj=[object Object]
urlString=http://user:pass@host.com:80/resource/path?query=string#hash
Resolving the URL Components
• Another useful feature of the url module is the ability to resolve URL components in
the same manner as a browser would.
• This allows you to manipulate the URL strings on the server side to make
adjustments in the URL.
• For example, you might want to change the URL location before processing the
request because a resource has moved or changed parameters.
• To resolve a URL to a new location use the following syntax:
• url.resolve(from, to)
• The from parameter specifies the original base URL string.
• The to parameter specifies the new location where you want the URL to resolve.
Resolving the URL Components
//Resolving the URL Components
var url = require('url');
var originalUrl = 'http://user:pass@host.com:80/resource/path?query=string#hash';
var newResource = '/another/path?querynew';
console.log(url.resolve(originalUrl, newResource));
Output:
http://user:pass@host.com:80/another/path?querynew
Processing Query Strings and Form Parameters
• HTTP requests often include query strings in the URL or parameter data in the
body for form submissions.
• The query string can be obtained from the URL object defined in the previous
section.
• The parameter data sent by a form request can be read out of the body of the
client request.
• The query string and form parameters are just basic key-value pairs.
• To actually consume these values in your Node.js webserver you need to
convert the string into a JavaScript object using the parse() method from the
querystring module:
• querystring.parse(str, [sep], [eq], [options])
Processing Query Strings and Form Parameters
• querystring.parse(str, [sep], [eq], [options])
• The str parameter is the query or parameter string.
• The sep parameter allows you to specify the separator character used. The
default separator character is &.
• The eq parameter allows you to specify the assignment character to use when
parsing. The default is =.
• The options parameter is an object with the property maxKeys that allows you
to limit the number of keys the resulting object can contain. The default is
1000. If you specify 0, there is no limit.
• You can also go back the other direction and convert an object to a query
string using the stringify() function shown here:
• querystring.stringify(obj, [sep], [eq]
Processing Query Strings and Form Parameters
//an example of using parse() and stringify() to parse a
query //string:
var qstring = require('querystring');
var params = qstring.parse("name=Brad&color=red&color=blue");
console.log(params)
var str = qstring.stringify(params);
console.log(str)
Output:
name=Brad&color=red&color=blue
Read the Query String
The function passed into the http.createServer() has a req argument that represents the
request from the client, as an object (http.IncomingMessage object).
This object has a property called "url" which holds the part of the url that comes after
the domain name:
//demo_url.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(req.url);
res.end();
}).listen(8080);
Read the Query String
Initiate demo_url.js:
http://localhost:8080/summer?year=2009&month=AUG
Will produce this result:
/summer?year=2009&month=AUG
http://localhost:8080/winter?year=2009&month=AUG
Will produce this result:
/winter?year=2009&month=AUG
Split the Query String
//write a Node JS program to read form data from query string and generate response
//using NodeJS.
var http = require('http');
var url = require('url');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
var q = url.parse(req.url, true).query;
var txt = q.year + " " + q.month;
res.end(txt);
}).listen(8080);
Output:
http://localhost:8080/?year=2017&month=July
Will produce this result:
2017 July
Understanding Request, Response, and Server Objects
• To use the http module in Node.js applications, you first need to understand
the request and response objects.
• They provide the information and much of the functionality that comes into
and out of the HTTP clients and servers.
• Once you see the makeup of these objects—including properties, events, and
methods they provide—it will be simple to implement your own HTTP servers
and clients.
• ClientRequest,
• ServerResponse,
• IncomingMessage,
• and Server objects
The http.ClientRequest Object
• The ClientRequest object is created internally when you call http.request() when
building the HTTP client.
• This object represents the request while it is in progress to the server. You use the
ClientRequest object to initiate, monitor, and handle the response from the server.
• The ClientRequest implements a Writable stream, so it provides all the functionality of a
Writable stream object.
• To implement a ClientRequest object, owing syntax:
http.request(options, callback)
• The options parameter is an object whose properties define how to open and send the
client HTTP request to the server.
• The callback parameter is a callback function that is called after the request is sent to the
server and handles the response back from the server.
• The only parameter to the callback is an IncomingMessage object that will be the
response from the server.
The http.ClientRequest Object
• The ClientRequest object provides several events that enable you to handle the various states
the request may experience.
The http.ClientRequest Object
• In addition to events, the ClientRequest object also provides several methods that can be
used to write data to the request, abort the request, or end the request.
The http.ServerResponse Object
• The ServerResponse object is created by the HTTP server internally when a
request event is received. It is passed to the request event handler as the second
argument.
• You use the ServerRequest object to formulate and send a response to the
client.
• The ServerResponse implements a Writable stream, so it provides all the
functionality of a Writable stream object.
• For example, you can use the write() method to write to it as well as pipe a
Readable stream into it to write data back to the client.
• When handling the client request, you use the properties, events, and methods
of the ServerResponse object to build and send headers, write data, and send
the response.
The http.ServerResponse Object
• Events available on ServerResponse objects
The http.ServerResponse Object (methods)
HTTP server
• To start the HTTP server, you need to first create a Server object using the
createServer() method shown below. This method returns the Server object.
• The optional requestListener parameter is a callback that is executed when the
request event is triggered.
• The callback should accept two parameters.
• The first is an IncomingMessage object representing the client request, and the
second is a ServerResponse object you use to formulate and send the response:
http.createServer([requestListener])
• Once you have created the Server object, you can begin listening on it by calling the
listen() method on the Server object:
• listen(port, [hostname], [backlog], [callback])
The http.ServerResponse Object(METHODS)-EXAMPLE
// code shows an example of starting an HTTP server and listening on port 8080.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World!');
res.end();
}).listen(8080);
Implementing HTTP Clients and Servers in Node.js
• 1. Serving Static Files
• The most basic type of HTTP server is one that serves static files.
• To serve static files from Node.js, you need to first start the HTTP server and listen on a
port.
• Then in the request handler, you open the file locally using the fs module and write the file
contents to the response.
Steps:
1. Create a file ‘httpstaticserver.js’ in current directory
2. Make a directory with name ‘html’ in the current directory
3. Create a new file ‘1.txt’ and ‘hello.html’ in ‘html ’ directory
4. Compile the file ‘httpstaticserver.js’
5. open the web browser and request ‘ localhost:8080/1.txt’ or ‘ localhost:8080/hello.html’
content of 1.txt or hello.html will be on the web page…
Implementing HTTP Clients and Servers in Node.js
// Write a Node JS program to demonstrate
//accessing static files using http webserver
and //client. fs.readFile(ROOT_DIR +
//httpstaticfileserver.js urlObj.pathname, function (err,data) {
if (err) {
var fs = require('fs');
res.writeHead(404);
var http = require('http'); res.end(JSON.stringify(err));
var url = require('url'); return;
var ROOT_DIR = "html/"; }
res.writeHead(200);
http.createServer(function (req, res) {
res.end(data);
var urlObj = url.parse(req.url, true, false); });
}).listen(8080)
Implementing HTTP Clients and Servers in Node.js
// Basic web client retrieving static files
// httpstaticfileclient.js response.on('end', function () {
var http = require('http'); console.log(serverData);
var options = { });
}
hostname: 'localhost',
http.request(options, function(response){
port: '8080', handleResponse(response);
path: '/hello.html' }).end()
};
function handleResponse(response) {
var serverData = '';
response.on('data', function (chunk) {
serverData += chunk;
});
Implementing HTTP Clients and Servers in Node.js
hello.html
<html>
<head>
<title>Static Example</title>
</head>
<body>
<h1>Hello from a Static File</h1>
</body>
</html>
Output:
Request: localhost:8080/hello.html
Output:
Hello from a Static File
Implementing HTTP Clients and Servers in Node.js
In modules/html/ 1.txt
1.txt
welcome to static file server......
Request: localhost:8080/1.txt
Output:
welcome to static file server......
In another terminal, run the file ‘httpstaticfileclient.js’
It will display the content of the file hello.html
Implementing HTTP Clients and Servers in Node.js
2.Implementing Dynamic GET Servers
• More often than not you will use Node.js webservers to serve dynamic content
rather than static content.
• This content may be dynamic HTML files or snippets, JSON data, or a number
of other data types.
• To serve a GET request dynamically, you need to implement code in the
request handler that dynamically populates the data you want to send back to
the client, writes it out to the response, and then calls end() to finalize the
response and flush the Writable stream.
Implementing HTTP Clients and Servers in Node.js
//Write a Node JS program to demonstrate accessing dynamic content through GET method using http webserver and
//client.(httpserverget.js)
var http = require('http');
var messages = [
'Hello World’,
'From a basic Node.js server’,
'Take Luck'];
http.createServer(function (req, res) {
res.setHeader("Content-Type", "text/html");
res.writeHead(200);
res.write('<html><head><title>Simple HTTP Server</title></head>');
res.write('<body>');
for (var idx in messages){
res.write('\n<h1>' + messages[idx] + '</h1>');
}
res.end('\n</body></html>');
}).listen(8080)
Implementing HTTP Clients and Servers in Node.js
http_client_get.js: Basic web client that makes a
GET request to the server
response.on('end', function () {
// Basic web client retrieving console.log("Response Status:",
var http = require('http'); response.statusCode);
console.log("Response Headers:",
var options = { response.headers);
hostname: 'localhost', console.log(serverData);
port: '8080', });
}; }
function
handleResponse(response) { http.request(options, function(response){
handleResponse(response);
var serverData = ''; }).end()
response.on('data', function
(chunk) {
serverData += chunk;
});
Implementing HTTP Clients and Servers in Node.js
Output:
1. Run the ‘httpserverget.js’ file
2. In the browser: localhost:8080 gives the response in web page.
Output:
Program Ended
hello world how are you
thank you
bye
Writable Streams
Writable streams are designed to provide a mechanism to write data
into a form that can easily be consumed in another area of code. Some
common examples of Writable streams are:
■ HTTP requests on the client
■ HTTP responses on the server
■ fs write streams
■ zlib streams
■ crypto streams
■ TCP sockets
■ Child process stdin
■ process.stdout, process.stderr
Writable Streams
Writable streams provide the write(chunk, [encoding], [callback])
method to write data into the stream, where chunk contains the data to
write, encoding specifies the string encoding if necessary, and callback
specifies a callback function to execute when the data has been fully
flushed.
The write() function returns true if the data was written successfully.
Writable streams also expose the following events:
■ drain: After a write() call returns false, the drain event is emitted to
notify listeners when it is okay to begin writing more data.
■ finish: Emitted when end() is called on the Writable object; all data is
flushed and no more data will be accepted.
■ pipe: Emitted when the pipe() method is called on a Readable stream to
add this Writable as a destination
unpipe: Emitted when the unpipe() method is called on a Readable
stream to remove this Writable as a destination.
Writable Streams
Writable stream methods:
Writable Streams
//write stream
var fs = require('fs');
var readableStream = fs.createReadStream('file1.txt');
var writableStream = fs.createWriteStream('file2.txt');
readableStream.setEncoding('utf8');
readableStream.on('data', function(chunk) {
writableStream.write(chunk);
});
console.log("data copied....from file1 to file2")
Writable Streams
Output:
File1.txt
hello world
how are you
File2.txt
hello world
how are you
Duplex Streams
• Duplex Streams implement both the Readable and Writable
interfaces.
• A prime example of Duplex Streams is a Socket.
• Sockets provide two passages for sending and receiving
information.
• Other examples of Duplex Streams are TCP sockets, zlib
streams, and crypto streams.
• When creating a Duplex Stream,
a) start off by implementing the required methods (File System), we’ll
be utilizing the PassThrough Stream which is a standard version of
Duplex and acts as a connecting tunnel between Readable Stream
and Writable Stream.
b) The next step is reading a file and including it into a Writeable
Stream with WriteStream.
Transform Streams
Another type of stream is the Transform stream.
• A Transform stream extends the Duplex stream but
modifies the data between the Writable stream and the
Readable stream.
• This can be useful when you need to modify data from
one system to another.
• Some examples of Transform streams are
■ zlib streams
■ crypto streams