I'm new to node.js and I'm trying to write a program that receives http requests and forwards the contents through a socket. At the other end of the socket is a paging system that needs messages terminated with a new line character. So far, it works fine, except there is an extra message sent with the contents: undefined.
When I print the contents of the pager message to the client's browser, there does not appear to be a new line. Am I doing this right?
sys = require("sys"),
http = require("http"),
url = require("url"),
path = require("path"),
net = require("net");
socket = new net.Socket();
socket.connect(4000, '192.168.0.105');
var httpServer = http.createServer(function(request, response) {
var uri = String(url.parse(request.url).query);
var message = uri.split("=");
var page = 'FPG,101,0,3!A' + message[0] + '\n';
response.writeHead(200, {"Content-Type":"text/html"});
response.write('sending message: ' + page + " to pager");
response.end();
socket.write(page);
}).listen(8080);
sys.puts("Server running at http://localhost:8080/");
EDIT: I narrowed it down further. It turns out that if I do:
var page = 'FPG,101,0,3!A' + 'hello' + '\n';
It works okay. So the output of uri.split("=") must not be what I am expecting.
I'm sure the new line is there, but you aren't going to see it when you send your Content-Type as text/html. In HTML, \n is just other whitespace, and is treated as such. Use text/plain instead.
Since content type is 'text/html',we can happily use break statement.Just like this
res.write('hello'+'<br/>');
res.write('nice to meet you');
You can try this code in node:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('hello,this is saikiran'+'<br/>');
res.end('nice to meet you');
}).listen(process.env.PORT || 8080);
console.log('server running on port 8080');
As per content type of text/plain, you can also use \r to send a return input
to the client's browser
I figured out what the problem was. For some reason the browser was sending an additional request to the page right after my request. I just filtered for requests with a certain format and that fixed it.
Consider using \\n instead of \n for new line.
Related
I'm currently teaching myself more about server code, specifically using Node.js and Express, and I'm having a lot of trouble with receiving and parsing a JSON object sent from a POST request. I have looked at numerous other posts (linked to below) and I can't figure out for the life of me what's going wrong. Here's what I've looked at:
Javascript: Send JSON Object with AJAX
Javascript : Send JSON Object with Ajax?
How do I consume the JSON POST data in an Express application
How do I consume the JSON POST data in an Express application
Send POST data using XMLHttpRequest
Send POST data using XMLHttpRequest
How do you extract POST data in Node.js?
How do you extract POST data in Node.js?
All of these are putting me on the right track, but I'm not quite there and thus looking for help. Here's the code I'm working with:
Send POST Request
var button = document.querySelector("#button");
button.onclick = function(){
console.log("Getting data from local server");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/data/test.json", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(JSON.stringify({"latitude": 41.2418, "longitude": -70.8898}));
};
Handle POST Request In Server
var http = require("http");
var fs = require("fs");
var express = require("express");
var app = express();
var path = require("path");
var bodyParser = require("body-parser");
var port = process.env.PORT || 3000;
//tells express where to find all the static files (HTML, CSS, etc) and load them into the browser
app.use(express.static(path.join(__dirname, '../client')));
//tells the application to use body-parser as middleware so it can handle post requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
//routing methods
//deal with incoming GET and POST requests to the server
app.get("/", function(req, res){
res.send("Submitted GET Request");
})
//only handles incoming POST requests to the test.json resource
app.post("/data/test.json", function(req, res){
console.info("Submitting POST Request to Server");
console.info("Request body: " + req.body);
//write the file
fs.writeFile(__dirname + "/../client/data/test.json", req.body,
function(err){
if(err){
console.error(err); //print out the error in case there is one
return res.status(500).json(err);
}
//resolve the request with the client
console.info("updated test.json");
res.send();
});
})
//tell the express object to create the server and listen on the port
app.listen(port);
console.log("Listening on localhost:" + port);
Whenever I try to print out the contents of "req.body" I get the output of "[object Object]". Any ideas?
EDIT:
My issue has been solved. I have changed
console.info("Request body: " + req.body);
To
console.info("Request body: " + JSON.stringify(req.body));
I also changed my Content-Type in my POST XMLHTTPRequest to "application/json" to help with formatting.
"[object Object]" is the default result of JavaScript's implicit toString operation, which it uses when trying to write a string representation of that object to the file.
Try writing JSON.stringify(req.data) to the file instead.
Also, on the client side – consider changing your Content-Type header to match:
xhr.setRequestHeader("Content-Type", "application/json");
If your post body is expected to be JSON, then change this line
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
To
xhr.setRequestHeader("Content-Type", "application/json");
I am following a tutorial on Node.js and I think I have done everything to the letter, I run my server (node web.js) and tried to connect to it but I am getting an error. My code is given below, I saw an answer to a similar question but I avoided the error there, I just don't know whats wrong. Please help!
var http = require("http");
function process_request(req, res) {
var body = 'Thanks for calling!\n';
var content_length = body.length;
res.writeHead(200, {
'Content-Length': content_length,
'Content-Type': 'text/plain'
});
}
var s = http.createServer(process_request);
s.listen(8080);
You need to write the content that you are sending back as a response. Add this after your res.writeHead().
res.write(body);
res.end();
You didn't provide the error, but you could try a
res.send(body);
Instead. Also confirm you're hitting http://localhost:8080/ (assuming it's running on localhost).
You are creating content but not sending to client , using res.end you can do like
res.write("Hello World");
res.end(body)
I'm new to node.js and I'm trying out a few easy examples using localhost:XXXX.
I want to read my request object from node. I have a book and in the book they use cURL(some program) to comunicate with node instead of the browser. Is it possible to write something in the browser adress field and send it to localhost and have a request object sent to node that looks exactly like if I had a typed in a url to a server somewhere? OIf so, how do I write? Do I have to use cURL or something like it if i use localhost?
I'm very new to node and javascript so I dont't know if I'm using the right words. I have tried to search but I dont't think I know the right terms to search for.
This is my server code:
var port = 3000;
http.createServer(function (req, res) {
var url = parse(req.url);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n' + url );
}).listen(port);
When i write http://localhost:3000/hello.com in the address field i was hoping i would get Hello world hello.com in the browser but i get hello world [object object]
Please help.
You can use your regular browser by testing it. In your URL address enter URL address that you have in your cURL address. For instance:
localhost:3000/index.html
If you would like to have more sophisticated tool that gives you more information about request/response you can use tool like Postman for that
In your code use:
res.end('Hello World\n' + url.parse(req.url, true));
url is an object, you need to specify property or method that you are calling on it.
Here is an example on how to parse URL. Easy URL Parsing With Isomorphic JavaScript:
Above answer given by #Vlad Beden looks good but you may want to play with following code
var http = require("http");
var port = 3000;
http.createServer(function (req, res) {
console.log('Requested method: ', req.method);
var params = parseUrl(req.url);
res.writeHead(200, { 'Content-Type': 'text/plain' });
var data = 'Hello World'
for(var i=0; i<params.length; i++)
data += '\n'+params[i]
res.end(data);
}).listen(port);
var parseUrl = function(url) {
var params = [];
if(url && url != '' && url != '/') {
url = url.replace(/^\/|\/$/g, '');
params = url.split('/');
}
return params;
}
You may try http://localhost:3000/hello.com or http://localhost:3000/hello.com/google.com/more.com/etc . I would like to recommend you print request object console.log(req) and have a look to understand url, method, headers, etc.
I'm trying to parse the url in node js. Getting null values from this code. It is receiving value for the path. But not for the host or protocol.,
var http = require('http');
var url = require('url');
http.createServer ( function (req,res){
var pathname = url.parse(req.url).pathname;
var protocol = url.parse(req.url).protocol;
var host = url.parse(req.url).host;
console.log("request for " + pathname + " recived.");
console.log("request for " + protocol + " recived.");
console.log("request for " + host + " recived.");
res.writeHead(200,{'Content-Type' : 'text/plain'});
res.write('Hello Client');
res.end();
}).listen(41742);
console.log('Server Running at port 41742');
console.log('Process IS :',process.pid);
The HTTP protocol doesn't communicate the combined URL in one value for Node to parse out.
A request to http://yourdomain.com/home, for example, arrives as:
GET /home HTTP/1.1
Host yourdomain.com
# ... (additional headers)
So, the pieces won't all be in the same place.
The path and query-string you can get from the req.url, as you were doing – it'll hold "/home" for the above example.
var pathname = url.parse(req.url).pathname;
The host you can get from the req.headers, though a value wasn't always required for it.
var hostname = req.headers.host || 'your-domain.com';
For the protocol, there isn't a standard placement for this value.
You can use the advice given in "How to know if a request is http or https in node.js" to determine between http and https.
var protocol = req.connection.encrypted ? 'https' : 'http';
Or, though it isn't standard, many clients/browsers will provide it with the X-Forwarded-Proto header.
req.url only contains the path not the entire url.
Rest are in request headers.
For Host: console.log(req.headers["host"]);
For Protocol: console.log(req.headers["x-forwarded-proto"]);
you can view this source code:
https://github.com/expressjs/express/blob/master/lib/request.js
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.