I'm learning Node.js I have created server and client .js files but I don't understand few things. For example, in the webserver.js file, I don't know what is the use of pathname. Similarly, in the client.js file, what are dataand path?
If you think I should read about the basics of it, please provide me a useful link if you can. I tried to find but didn't work.
webserver.js
var fs=require('fs');
var url=require('url');
var http=require('http');
http.createServer(function(request, response){
var pathname=url.parse(request.url).pathname;
console.log("Pathname: "+pathname+"Request.url: "+request.url);
fs.readFile(pathname.substr(1), function(err, data){
if(err){
console.log("Error reading.");
response.writeHead(400, {'content-type' : 'text/html'});
}else{
response.writeHead(200, {'content-type' : 'text/html'});
response.write(data.toString());
}
response.end();
});
}).listen(8081);
console.log("Server is running.");
client.js
var http=require('http');
var options={
host: 'localhost',
port: '8081',
path: '/index.html'
};
var callback=function(response){
var body='';
response.on('data', function(data){
body+=data;
});
response.on('end', function(){
console.log("Data received.");
});
}
var req=http.request(options, callback);
req.end();
The original code souce is here: Code
pathname is the path section of the URL, that comes after the host and before the query, including the initial slash if present.
pathname is the path requested to the http server. The example pathname for this question is /questions/40276802/what-is-client-path-and-data-in-this-code. The path in client.js is the same deal.
You can find documentation on parsing the URL into the pathname from the Node.js docs: https://nodejs.org/api/http.html#http_message_url
Node's HTTP client uses streams, which emit several events. data is called with a buffer, which you usually will add to an array then concat later (as the code does). end is called when all buffers are sent.
You can find documentation on handling events from streams from the Node.js docs: https://nodejs.org/api/stream.html#stream_class_stream_readable
pathname is the requested path. You should check the documentation for the url package: npm-url
In your client.js: data is the response data from the server. Again check http documentation: HTTP|Node.js
For learning callbacks and all about Node.js: nodeschool.io
Related
I am a beginner to node.js and i did a sample code it shown below,
var http = require("http");
var server = http.createServer(function(request,response) {
response.writeHead(200, {
"content-Type" : "text/html"
});
response.end("Hello again");
}).listen(8888);
and when i run this file on eclise Run as ------> Node project
and when i open the browser with url localhost:8888 it shows web page not availble. can u guys help me to find out. I already installed node.js on my system and npm alse. am i missing something?
There is no request or response object in the scope of your request callback. You need to define them as arguments of the callback function.
var http = require("http");
var server = http.createServer(function(request, response) {
response.writeHead(200, {
"content-Type" : "text/html"
});
response.end("Hello again");
}).listen(8888);
You should definitely get an error though - are you sure your IDE is set up properly?
You never accept the "request" variable. Below is a working version of what you're attempting.
var http = require("http");
var server = http.createServer();
server.on('request', function(request, response) {
response.writeHead(200, {
"content-Type" : "text/html"
});
response.end("Hello again");
});
server.listen(8888);
Can you please tell me where you found response object? http.createServer return a callback function which have two arguments. They are response and request. response use for send data/information to client and request use for get data/information from client. So in your http.createServer callback function add response and request arguments. After that in callback function use response object. Like this.
var http = require("http");
var server = http.createServer(function(request, response) {
response.writeHead(200, {
"content-Type" : "text/html"
});
response.end("Hello again");
}).listen(8888);
I'm having trouble wrapping my head around the pipe function shown in several Node.js examples for the net module.
var net = require('net');
var server = net.createServer(function (socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
Can anyone offer an explanation on how this works and why it's required?
The pipe() function reads data from a readable stream as it becomes available and writes it to a destination writable stream.
The example in the documentation is an echo server, which is a server that sends what it receives. The socket object implements both the readable and writable stream interface, so it is therefore writing any data it receives back to the socket.
This is the equivalent of using the pipe() method using event listeners:
var net = require('net');
net.createServer(function (socket) {
socket.write('Echo server\r\n');
socket.on('data', function(chunk) {
socket.write(chunk);
});
socket.on('end', socket.end);
});
pipe() reads from a readable stream and writes to a writeable stream, much like a Unix pipe. It does all "reasonable" things along the way with errors, end of files, if one side falls behind etc. Your particular example is slightly confusing because the socket is both readable and writeable.
An easier to understand example is in this SO question where you read from an http request and write to an http response.
There are 2 sockets per Server-Client Connection (2 endpoints). Socket binds IP Address:Port Number. The client gets assigned random port numbers, while the server has dedicated port number. This is the basic explanation of how socket works.
Piping is reserved for redirecting a readable stream to a writable stream.
What socket.pipe(socket) does?
It redirects all the data from the readable stream (server) to the writable stream (client). We can tweak this by adding event listeners as #hexacyanide has pointed out.
Consider the following request handler
var server = http.createServer(function(req, res){
console.log('Request for ' + req.url + ' by method ' + req.method);
if(req.method == 'GET'){
var fileurl;
if(req.url == '/')fileurl = '/index.html';
else {
fileurl = req.url;
}
}
var filePath = path.resolve('./public'+fileurl);
var fileExt = path.extname(filePath);
if(fileExt == '.html'){
fs.exists(filePath, function(exists){
if(!exists){
res.writeHead(404, {'Content-Type': 'text/html'});
res.end('<h1>Error 404' + filePath + 'not found </h1>');
//the end() method sends content of the response to the client
//and signals to the server that the response has been sent
//completely
return;
}
res.writeHead(200, {'Content-Type':'text/html'});
fs.createReadStream(filePath).pipe(res);
})
}
}
The fs.createReadStream method reads the file in the given file path (public/index.html) and pipe() writes it to the response (res) for client's view.
I am trying to pipe images from an Amazon S3 server through my node server while adding a custom header to the response.
Right now, however, the server will respond with a plain "Document" that will download to my computer with no file extension declared. The "Document" still contains the desired image data, but how can I make it clear that this is a PNG that can be viewed in my browser?
Here's my current code:
app.get('/skin', function (req, res) {
res.writeHead(200, {'Content-Type': 'image/png', 'access-control-allow-origin': '*'});
http.get("http://s3.amazonaws.com/MinecraftSkins/clone1018.png").pipe(res);
});
You might want to use http.request in order to make nice proxying and resource loading with duplicating headers.
Here is example in express that will listen on port 8080, and will make request to specific server with actually url that you request from /skin/* route:
var http = require('http'),
express = require('express'),
app = express();
app.get('/skin/*', function(req, res, next) {
var request = http.request({
hostname: 's3.amazonaws.com',
port: 80,
path: '/' + req.params[0],
method: req.method
}, function(response) {
if (response.statusCode == 200) {
res.writeHead(response.statusCode, response.headers);
response.pipe(res);
} else {
res.writeHead(response.statusCode);
res.end();
}
});
request.on('error', function(e) {
console.log('something went wrong');
console.log(e);
})
request.end();
});
app.listen(8080);
In order to test it out, run it on your machine, and then go to: http://localhost:8080/skin/nyc1940/qn01_GEO.png
It will load that image proxying from Amazon, and returning its headers as well. You might customize headers as well, in order to prevent XML being sent from S3 (when file does not exist).
You dont need to set any headers as they are proxied from s3.amazon and it does reliably set right headers for you.
Nor access-control-allow-origin as you will need it only in case with AJAX request to resource from another domain name. But anyway feel free to modify response.headers before sending out. It is simple object (console.log it for tests).
I have a image pic.jpeg which I have to display on browser.Here is snippet of code I have written.
var mimeTypes = {
'.js' : 'text/javascript',
'.css' : 'text/css',
'.gif' : 'image/gif',
'.jpeg': 'image/jpeg',
'.html': 'text/html'
};
contenttype = mimeTypes[path.extname(req.url)];
pathname = "." + req.url;
var stream = fs.createReadStream(pathname);
stream.on('error', function(error) {
res.writeHead(500);
res.end();
return;
});
res.setHeader('Content-Type', contenttype);
res.writeHead(200);
stream.on('open', function () {
// This just pipes the read stream to the response object (which goes to the client)
util.pump(stream, res, function(error) {
//Only called when the res is closed or an error occurs
console.log("Error:");
res.end();
return;
});
});
The above code works most of the time and the images displays like it should, but at times the image is missing.
You should not be serving static files through node.js. You should consider using Nginx or similar web server for the same.
Alternatively, you can use connect module to serve static files
var server = connect()
.use('/static', connect.static(__dirname + '/static'))
.use(router)
.listen(port);
Make a new directory named static and put all files in it, so you will be able to access them by /static/images/testimage.jpg
Rather than implementing static file serving yourself, why not use a library like Express? You can see that being used here: Express Static nodejs or see the API here: http://expressjs.com/api.html (search for "static"). It'll be a lot less code, and reliable.
i'm fetching some binary data over http. My code looks like:
var writeStream = fs.createWriteStream(fileName);
request(url, function(err, res) {
res.socket.pipe(writeStream);
});
now the output file is created but the filesize is 0. The url is correct though, i verified that with wget.
Thanks in advance & best regards
The callback for http.request only supplies one argument, which is a reference to the response of the request. Try
http.request(url, function(res) {
res.pipe(writeStream);
});
Also note that the ClientResponse implements ReadableStream, so you should use .pipe rather than .socket.pipe.
I'm assuming that here request is from mikeal's request library rather than being an instance of http.request. In that case you can simply do request(url).pipe(writeStream);
Remember that for debugging purposes, you can always pipe to process.stdout.
var readStream = fs.createReadStream(fileName);
request(url, function(err, res) {
readStream.pipe(res);
readStream.on('end', function() {
//res.end({"status":"Completed"});
});
});