I am running the following code snippet from the node js beginner book.
var http = require("http");
var url = require("url");
function onRequest(request, response) {
console.log("request url issss " + request.url);
var pathName = url.parse(request.url).pathName;
console.log("Request for " + pathName + " received");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello Worldd");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started11.");
Now while hitting http://localhost:8888/start in the browser, i am getting request.url is start only instead of full url. Hence path name is coming undefined.
Following is the console out put
Server has started11.
request url issss /start/
Request for undefined received
Thanks,
Shantanu
It's pathname with the n lowercased.
Also, request.url does not contain the fully qualified URL, it only contains the requested URL that the client sends.
Related
The following server is supposed to :
CASE #1 : serve mysitename.html if the request is http://localhost:8080
CASE #2 : serve the relevant file if the request is e.g. http://localhost:8080/mysitename.html
CASE #3 send me an email if the request is http://localhost:8080/contactform?name=..&..&...etc.
If I visit http://localhost:8080/mysitename.htmleverything works fine. mysitename.html is loaded and then all subsequent content (.js, .css, .png etc.) is loaded through it.
PROBLEM : However, if I visit http://localhost:8080, the following happens :
I get a Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING error on the browser's (Chrome) console.
`mysitename.html' appears corrupted on the client. Parts of the DOM are missing and when I try to view the source page, it just hangs and never actually loads. Loading only part of the DOM is weird given that all DOM elements of this file are static/hardcoded.
What's confusing is that the rest of the content (.js, .css etc..) is loaded but nothing actually shows because of the corrupted .html. Is it possible that CASE#1 is interrupted by CASE#2 that follows right after it? What exactly am I doing wrong ?
CASE#2 initially had an error which was causing an infinite loop found by Johnny Estilles (see his answer below). This has since been fixed but the issues mentioned above now occur.
server.js
// setting up email handler
var nodemailer = require('nodemailer');
var emailHandlerService = 'Gmail';
var emailHandlerAddress = ******;
var emailHandlerPassword = ******;
var transporter = nodemailer.createTransport({
service: emailHandlerService,
auth: {
user: emailHandlerAddress,
pass: emailHandlerPassword
}
});
// setting up http server
var http = require('http');
var fs = require('fs');
var url = require("url");
var path = require("path");
var rootDir = __dirname + "/public";
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
/* Even though the js mime type is set as well, scripts are still sent
as "text/plain" according to the Chrome console. Why is that ? */
"js": "application/javascript",
"css": "text/css",
"ico": "image/ico"
};
// initializing server
var httpServer = http.createServer(function (request, response)
{
// CASE #1
// if the user is on http://localhost:8080, load public/mysitename.html
if (request.url === "/")
{
fs.readFile('public/mysitename.html', function (err, html)
{
if (err)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
throw (err);
}
else
{
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
}
});
}
// CASE #2
// else if this is a contact form data request
// forward the data to my email (I'll make a more precise Regex for the request)
else if (/contactform/.test(request.url))
{
var parsedURL = url.parse(request.url, true);
var name = parsedURL.query.name;
var email = parsedURL.query.email;
var subject = parsedURL.query.subject;
var enquiry = parsedURL.query.enquiry;
var browser = parsedURL.query.browsername + " " +
parsedURL.query.browserversion;
transporter.sendMail({
from: emailHandlerAddress,
to: emailHandlerAddress,
subject: subject,
text: "|| NAME = " + name + " || EMAIL = " +
email + " || BROWSER = " + browser + " || DEVICE = " +
parsedURL.query.device + " || ENQUIRY = " + enquiry
});
response.end(JSON.stringify(parsedURL.query));
}
// CASE #3
// if none of the above is true then this is a request to serve static files
else
{
var pathname = url.parse(request.url).pathname;
var filename = path.join(rootDir, pathname);
fs.exists(filename, function (exists)
{
if (!exists)
{
fs.readFile('public/404.html', function (err, html)
{
if (err)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
throw (err);
}
else
{
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
}
response.end();
});
}
else
{
var requestedFileExtension = path.extname(filename).split(".")[1];
var mimeType = mimeTypes[requestedFileExtension] || 'text/plain';
// as I noted above, this doesn't seem to have any effect
// for my .js files
response.writeHead(200, mimeType);
var fileStream = fs.createReadStream(filename);
fileStream.pipe(response);
}
});
}
}).listen(8080);
FIXING ISSUE #1: Infinite loop
You're missing an equal sign (or two) in your initial if().
Change
if (request.url = "/")
to
if (request.url == "/")
or
if (request.url === "/")
FIXING ISSUE #2: Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING
Your're missing a response.end() in CASE #1.
// CASE #1
// if the user is on http://localhost:8080, load public/mysitename.html
if (request.url === "/")
{
fs.readFile('public/mysitename.html', function (err, html)
{
if (err)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
throw (err);
}
else
{
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
}
response.end(); // <-- MISSING
});
}
I'm trying to get node.js to print http request properties to the browser. However, the properties of the request url either return null or don't print at all. Here is the code for the server (server.js):
var http = require('http');
var url = require('url');
function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url, true).pathname;
var protocol = url.parse(request.url, true).protocol;
var hostname = url.parse(request.url, true).host;
var path = url.parse(request.url, true).path;
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World"); //this is the text that is sent back
response.write("\nThe HTTP response is " + response.statusCode);
response.write("\nRequest for "+ pathname +" has been received. The request url is " + request.url + " and our protocol is " + protocol +".Also, our host is " + hostname);
response.write("\nThe concatenated path is " + path);
response.end(); //this is the end of the response
}
var new_server = http.createServer(onRequest).listen(8888);
} //end of start function
exports.start = start;
And the index file that executes this is index.js
var server = require("./server");
console.log("To see what the sever responds with, go to localhost:8888.");
server.start();
My browser output is, when I type in the url bar localhost:8888
Hello World
The HTTP response is 200
Request for / has been received. The request url is / and our protocol is null.Also, our host is null
The concatenated path is /
I need to get the url properties. Thank you.
The reason these variables are returning undefined is because the url only contains the path. The protocol and the host are stored elsewhere. Take this example from the node.js documentation:
var url = require('url');
console.log( url.parse(
'http://user:pass#host.com:8080/p/a/t/h?query=string#hash', true
));
That will return the following object:
{
href: 'http://user:pass#host.com:8080/p/a/t/h?query=string#hash',
protocol: 'http:',
host: 'user:pass#host.com:8080',
auth: 'user:pass',
hostname: 'host.com',
port: '8080',
pathname: '/p/a/t/h',
search: '?query=string',
query: { query: 'string' },
hash: '#hash',
slashes: true
}
These values are present in the URL, so they are present in the object. The localhost:8888 URL has none of these.
On another note, there are three important aspects to the request object: the url, the method, and the headers. If you try doing this, I suspect you will find the information you're looking for:
var urlStr = 'http://' + req.headers.host + req.url,
parsedURL = url.parse( urlStr ,true );
console.log(parsedURL);
//this should give you the data you are looking for.
I have been trying to get my server to work but when I send post data it just keeps loading and no results are given. Here is my noen.js file.
var http = require('http');
var url = require('url');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {sys.puts(stdout)}
exec ("casperjs test.js " + queryData.name + '\n');
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(1213);
Can anyone help me fix this? When I go to
127.0.0.1:8000/?name=tom
I get no response the page just goes into a long loading loop
There is no response.end in case if is true so then response "never" ends.
write at bottom of the if
response.end("something");
And you will get the response;
For get the output of the process to the response:
https://stackoverflow.com/a/3944751/3018595
var http = require('http');
var url = require('url');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var exec = require('child_process').exec;
exec ("casperjs test.js " + queryData.name + '\n',function(err, stdout, stderr) {
response.end(stdout);
});
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(1213);
The reason your browser is keep waiting because you are not ending your response. You have to call response.end to let your server complete the response otherwise it will keep thinking that the response is not complete yet. I added a line in your if statement and tested your code and it is working perfectly fine.
added line ** response.end("Request processed successfully...\n");**, assuming that you need to display a different message in case your "else" statement.
I tested url http://:1213/?name=tom
var http = require('http');
var url = require('url');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {sys.puts(stdout)}
exec ("casperjs test.js " + queryData.name + '\n');
response.end("Request processed successfully...\n");
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(1213);
If the request contains a header such as:
Authorization: Digest username="Mufasa",
realm="testrealm#host.com",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"
Does node have any built-in way to extract the key value pairs? Or should I just use string.split?
Use the URL module http://nodejs.org/api/url.html
Example: http://www.host.com:8080/path?name=daniel
Takes a URL string, and return an object.
url.parse(urlStr, [parseQueryString], [slashesDenoteHost])
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
response.end('Hello ' + queryData.name + '\n');
}
In this example name is mapped to daniel.
Before I begin I'd like to tell all of you that I made a lot of searching for solution of this problem on my own.
Here is my nodejs server:
var http = require('http');
http.createServer(function (req, res) {
console.log("Recived request url " + req.url);
var sname = req.url.search("name");
if(sname != -1){
sname = sname + "name".length + 1;
var from = sname;
while(req.url[sname] != '?' && sname<req.url.length){
sname++;
}
var name = req.url.substring(from,sname);
console.log("Returning parameter of name - " + name);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(name+'\n');
}
else{
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Error - ask about name\n');
}
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
It listens on port 1337 and if request url is correct it returns some string.
Here is my javascript code asking nodejs for answer.
function httpGet(theUrl){
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, true );
xmlHttp.send( null );
return xmlHttp.responseText;
}
var url = httpGet("http://127.0.0.1:1337/?name=Mateusz");
setTimeout(function(){
document.getElementById("actualnewsspace").innerHTML=url;
var xurl = httpGet("http://127.0.0.1:1337/?"+url);
},5000)
returned xmlHttp.responseText is blank.
Why? That's my question.
That's what my nodejs server has to say in this matter
Recived request url /?name=Mateusz
Returning parameter of name - Mateusz
Recived request url /?
If I curl my server it returns mi proper value.
xmlHttp.responseText hasn't been populated when you return it. Ajax is Asynchronous.
See Using XMLHttpRequest and bind an event handler to listen for when the HTTP response has arrived and process the data in that.