i am newbie to node.js.
I was trying to implement danielnill example tutorial
server.js
var http = require("http");
var url = require('url');
var fs = require('fs');
var io = require('socket.io');
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
switch(path){
case '/':
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world');
break;
case 'socket.html':
fs.readFile(__dirname + path, function(error, data){
if (error){
response.writeHead(404);
response.write("opps this doesn't exist - 404");
}
else{
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data, "utf8");
}
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404");
break;
}
response.end();
});
server.listen(8001);
io.listen(server);
socket.html
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<script>
var socket = io.connect();
</script>
<div>This is our socket.html file</div>
</body>
</html>
when ever i am trying run this http://localhost:8001/socket.html url from browser. Its goes to default case instead going to 'socket.html' case.
Pls help me to execute 'socket.html' case in this example.
There are two issues with what you have posted:
The path variable equals /socket.html when the URL http://localhost:8001/socket.html is requested, not socket.html; you need to update the case statement accordingly.
The fs.readFile callback will not be able to write the response to back to the client (browser), as response.end(); will have already been called; you need to move response.end() into each of the case statements.
Here is the updated code:
var http = require("http");
var url = require('url');
var fs = require('fs');
var io = require('socket.io');
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
switch(path){
case '/':
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world');
response.end();
break;
case '/socket.html':
fs.readFile(__dirname + path, function(error, data){
if (error){
response.writeHead(404);
response.write("opps this doesn't exist - 404");
}
else{
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data, "utf8");
}
response.end();
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404");
response.end();
break;
}
});
server.listen(8001);
io.listen(server);
Related
I have read many questions regarding "unable to load js and css files from node js". Looks like a silly path error but since am new to node js, am unable to figure it out.
All of my files are under one folder named "d3". Any ideas where am going wrong?
var http = require('http');
var fs = require('fs');
var url = require('url');
var io = require('socket.io');
var redis = require('redis');
var redis = require("redis")
, subscriber = redis.createClient();
subscriber.subscribe('channel');
var server = http.createServer(function(request, response){
var path = url.parse(request.url).pathname;
switch(path) {
case '/socket.html':
fs.readFile(__dirname + path, function(error, data){
if (error){
console.log("Working " + error);
response.writeHead(404);
response.write("File doesn't exist - 404");
response.end();
}
else{
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data, "utf8");
response.end();
}
});
break;
default:
response.writeHead(404);
response.write("Doesnt Exist");
response.end();
break;
}
});
/* Rest of the code */
server.listen(8000);
When node JS gets a request, you pass the requested path into a switch statement.
If the request is for /socket.html you return an HTML document.
If the request if for anything else (such as my.js), you return a 404 error.
You have to return the JS and CSS when it is requested instead of throwing a 404.
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 run some simple codes of node.js, this hello world works without a problem:
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Este node.js criou um servidor\n");
});
server.listen(8000);
But when I try to run this one that should be simple enough, the browser (tried IE and chrome) stays loading for a long time and then gives a timeout. What could be the problem?
var http = require("http"),
fs = require("fs");
http.createServer(function (request, response) {
request.on('end', function () {
if (request.url == '/') {
fs.readFile('test.txt', 'utf-8', function (error, data) {
response.writeHead(200, {
'Content-Type': 'text/plain'
});
data = parseInt(data) + 1;
fs.writeFile('test.txt', data);
response.end('This page was refreshed ' + data + ' times!');
});
} else {
response.writeHead(404);
response.end();
}
});
}).listen(8000);
By the way, I've created the test.txt file in the same folder as the code and it have only the number 1 inside it.
The end request never launch, because the request is finished when the server is called. Remove that line and ready like this:
var http = require("http"),
fs = require("fs");
http.createServer(function (request, response) {
// request.on('end', function () {
if (request.url == '/') {
fs.readFile('test.txt', 'utf-8', function (error, data) {
response.writeHead(200, {
'Content-Type': 'text/plain'
});
data = parseInt(data) + 1;
fs.writeFile('test.txt', data);
response.end('This page was refreshed ' + data + ' times!');
});
} else {
response.writeHead(404);
response.end();
}
// });
}).listen(8000);
The request object from a HTTP handler is an instance of readable stream, which will not emit the end event when in non-flowing mode. If an end event is expected, then the stream must be resumed..
If you aren't going to collect the body of the request, then you don't need to listen for the end event at all. You can just write the response:
http.createServer(function(req, res) {
if (request.url == '/') {
fs.readFile('test.txt', 'utf-8', function (error, data) {
res.writeHead(200, {'Content-Type': 'text/plain'});
data = parseInt(data) + 1;
fs.writeFile('test.txt', data);
res.end('This page was refreshed ' + data + ' times!');
});
} else {
res.writeHead(404);
res.end();
}
}).listen();
Otherwise, the stream can converted to flowing mode by either of these:
req.resume();
req.on('data', function(chunk) {});
The way that it seems to be structured is quite different from what I have seen otherwise. You shouldn't need the request.on structure. Generally, you could using something like this:
var http = require("http");
var Start = function(){
var onRequest = function(request, response){
response.writeHead(200, {"Content-Type" : "text/plain" });
response.write("HEllo World");
response.end();
}
http.createServer(onRequest).listen(8888);
}
exports.Start = Start;
The reason for the exports is so that you can start it form another file (which is good if you are going for the suggested modular design. As to loading files - your way of loading may work, but the problem is that it will only server text file - trying to use an html file will fail miserably, and you probably want to be serving html files as well, along with .js and .css files as well (and anything else, for example pictures). Therefore, please refer to my answer, which is the very long one with plenty of code, in the folllowing link: Click Here.
I'm a beginner of node.js and javascript.
I want to include external javascript file in html code. Here is the html code, "index.html":
<script src="simple.js"></script>
And, here is the javascript code, "simple.js":
document.write('Hello');
When I open the "index.html" directly on a web browser(e.g. Google Chrome), It works.
("Hello" message should be displayed on the screen.)
However, when I tried to open the "index.html" via node.js http server, It doesn't work.
Here is the node.js file, "app.js":
var app = require('http').createServer(handler)
, fs = require('fs')
app.listen(8000);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
("index.html", "simple.js" and "app.js" are on same directory.)
I started the http server. (by "bash$node app.js")
After then, I tried to connect "localhost:8000".
But, "Hello" message doesn't appear.
I think the "index.html" failed to include the "simple.js" on the http server.
How should I do?
Alxandr is right. I will try to clarify more his answer.
It happens that you have to write a "router" for your requests. Below it is a simple way to get it working. If you look forward www.nodebeginner.org you will find a way of build a proper router.
var fs = require("fs");
var http = require("http");
var url = require("url");
http.createServer(function (request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
response.writeHead(200);
if(pathname == "/") {
html = fs.readFileSync("index.html", "utf8");
response.write(html);
} else if (pathname == "/script.js") {
script = fs.readFileSync("script.js", "utf8");
response.write(script);
}
response.end();
}).listen(8888);
console.log("Listening to server on 8888...");
The problem is that nomatter what your browser requests, you return "index.html". So the browser loads your page and get's html. That html includes your script tag, and the browser goes asking node for the script-file. However, your handler is set up to ignore what the request is for, so it just returns the html once more.
Here is a working code.
There should be more cleaner simpler code, but this is very close to minimal.
This code suppose your index.html and other files are under /client dir.
Good luck.
var fs = require('fs');
var url = require("url");
var path = require('path');
var mime = require('mime');
var log = console.log;
var handler = function (req, res)
{
var dir = "/client";
var uri = url.parse(req.url).pathname;
if (uri == "/")
{
uri = "index.html";
}
var filename = path.join(dir, uri);
log(filename);
log(mime.lookup(filename));
fs.readFile(__dirname + filename,
function (err, data)
{
if (err)
{
res.writeHead(500);
return res.end('Error loading index.html');
}
log(data);
log(filename + " has read");
res.setHeader('content-type', mime.lookup(filename));
res.writeHead(200);
res.end(data);
});
}
Your handler is hardcoded to always return the content of /index.html. You need to pay attention to the resource that is being requested and return the right one. (i.e. if the browser asks for simple.js then you need to give it simple.js instead of index.html).
function contentType(ext) {
var ct;
switch (ext) {
case '.html':
ct = 'text/html';
break;
case '.css':
ct = 'text/css';
break;
case '.js':
ct = 'text/javascript';
break;
default:
ct = 'text/plain';
break;
}
return {'Content-Type': ct};
}
var PATH = 'C:/Users/DELL P26E/node_modules'
var http = require("http");
var fs = require('fs');
var url = require("url");
var path = require("path")
var fileName = "D:/index.html";
var server = http.createServer (function (request, response) {
var dir = "D:/";
var uri = url.parse(request.url).pathname;
if (uri == "/") {
uri = "index.html";
}
var filename = path.join(dir, uri);
fs.readFile(filename,
function (err, data) {
if (err) {
response.writeHead(500);
return response.end('Error loading index.html');
}
var ext = path.extname(filename)
response.setHeader('content-type',contentType(ext));
response.writeHead(200);
response.end(data);
});
}).listen(3000);
console.log('Server running on 8124') ;
Here is my code.
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
path = path.substr(1);
switch(path){
case '':
response.writeHead(200, {'Content-Type':'text/html'});
response.end();
break;
case 'socket.html':
response.write("read file"); //works
fs.readFile(__dirname + '\\' + path, function(error, data){
if (error){
response.writeHead(404); //this doesn't work
}
else{
response.writeHead(200, {'Content-Type':'text/html'}); //doesn't work
response.write("OK"); //doesn't work
}
});
response.end();
break;
default:
response.writeHead(404);
response.end();
break;
}
});
The server listens on port 8001 and when I visit http://myhost.com:8001/socket.html, I can only see "read file". Methods in response seems like broken in the callback function readFile.
Can somebody tell my why and give me a solution? Thanks!
(Forgive my poor English :) ).
You're ending the response too early. The function you pass to readFile is an asynchronous callback, which runs after the whole switch statement.