I am new to node.js and have been trying to setup just a basic server to start with.
I have the code below running and I get a "Write After End" error.
Socket.html is a basic html file that has a hello world string in the body. There is literally nothing else in that file. I have tried using the "ReadFileSync" method and that throws up a whole new set of errors that I don't fully understand.
I will appreciate any help on this. I am brand new to this so please go a little easy on me :) Thank you in advance!
I have verified that the path is correct, and that the buffer does have the data.
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname.substr(1);
path = "\\" + path;
switch(path){
case '/':
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world');
break;
case '\\socket.html':
//console.log(path);
fs.readFile(__dirname + path, function(error, data){
if(error){
response.writeHead(404);
response.write("This domain is missing");
}
else{
console.log(data);
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data,"utf8");
}
});
break;
default:
response.writeHead(404);
response.write("This domain is missing");
break;
}
response.end();
});
server.listen(8001);
I think when you read from the FileSystem async, the response.end() method is called before response.write() I would suggest using the following code instead:
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(request, response) {
var path = url.parse(request.url).pathname.substr(1);
path = "\\" + path;
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("This domain is missing");
} else {
response.writeHead(200, {"Content-Type": "text/html"});
response.write(data, "utf8");
}
response.end();
});
break;
default:
response.writeHead(404);
response.write("This domain is missing");
response.end();
break;
}
});
Related
I've been learning Node and although I understand all the code, and what is does, one thing is bothering me. So this is the code:
const http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
// array of mime types
var mimeTypes = {
"html" : "text/html",
"jpeg" : "image/jpeg",
"jpg" : "image/jpeg",
"png" : "image/png",
"js" : "text/javascript",
"css" : "text/css"
}
// create Server
http.createServer( (req, res) => {
var uri = url.parse(req.url).pathname;
var fileName = path.join(process.cwd(),unescape(uri));
console.log('Loading ' + process.cwd() + uri);
var stats;
try{
stats = fs.lstatSync(fileName);
} catch(err) {
res.writeHead(404, {'Content-Type' : 'text/plain'});
res.write('404 Not found\n');
res.end();
return; // if I remove this my code fails.
}
// check if file or directory
if (stats.isFile()) {
var mimeType = mimeTypes[path.extname(fileName).split(".").reverse()[0]]
res.writeHead(200, {'Content-Type': mimeType});
var fileStream = fs.createReadStream(fileName);
fileStream.pipe(res);
} else if (stats.isDirectory()) {
res.writeHead(200 , {
"Location" : "index.html"
});
res.end();
} else {
res.writeHead(500, {"Content-Type" : "text/plain"});
res.write("500 Internal Error\n");
res.end();
}
}).listen(8080);
So If I remove blank return inside catch block my code will fail.
With return:
Without return:
Does return allows execution to continue, can anyone explain?
Thanks.
If you will not return inside the catch block - the code will continue to run and will get to the following line:
stats.isFile()
Now, stats is not defined, since there was an exception there, so your code is actually undefined.isFile(), and this will throw another exception there.
I think you expect that the res.end() will stop the function execution / request processing, but instead it only closes the response body. The response then can be returned but your code after try / catch block goes on and experiences problems. The only proper way to stop the execution is your return; statement.
I am trying to create an HTTP server that the user can upload images and archives, and for that I am using formidable for handling the upload part.
My code :
requestHandler.js
// Request Handlers (will handle all requests that happen)
// Allows Node.js to make use of a non-blocking operation: exec ();
var exec = require("child_process").exec;
var querystring = require("querystring");
fs = require("fs");
var fomidable = require("formidable");
function start(response, postData) {
console.log("Request handler 'start' was called");
var body = '<html>' +
'<head>' +
'<meta http-equiv = "Content-Type" content = "text/html";'+
'charset="UTF-8"/>' +
'</head>' +
'<body>' +
'<form action = "/upload" enctype = "multipart/form-data"' +
'method = "post">' +
'<input type ="file" name = "upload multiple = "multiple">' +
'<input type = "submit" value ="Upload file" />' +
'</form>' +
'</body>' +
'</html>';
response.writeHead(200, {"Content-Type" : "text/html"});
response.write(body);
response.end();
}
// What is being passed between router.js and requestHandler.js is the entire body of the POST data request.
function upload(response, request) {
console.log("Request handler 'upload' was called");
var form = new formidable.IncomingForm();
console.log("about to parse");
form.parse(request, function(error, fields, files) {
console.log("parsing done");
/*Possible error on Windows systems; tried to rename to an already existing file*/
fs.rename(files.upload.path, "/tmp/test.png", function(err) {
if(err) {
fs.unlink("/tmp/test.png");
fs.rename(files.upload.path, "/tmp/test.png");
}
});
response.writeHead(200, {"Content-Type" : "text/plain"});
response.write("You've sent the text : " + querystring.parse(postData).text);
response.write("\nHello Upload");
response.end();
});
}
function show(response) {
console.log("Request handler 'show' was called.");
fs.readFile("/tmp/test.png", "binary", function(error,file) {
if(error) {
response.writeHead(500, {"Content-Type" : "text/plain"});
response.write(err + "\n");
response.end();
} else {
response.writeHead(200, {"Content-Type" : "image/png"});
response.write(file, "binary");
reponse.end();
}
});
}
exports.start = start;
exports.upload = upload;
exports.show = show;
I am using too formidable in the another part of my code, in my server.js but there for some reason works (And for that reason I am not posting the code), the error point out to requestHandler.js in line 35 :
var form = new formidable.IncomingForm();
formidable is not defined
How can I make formidable defined ? When I am already doing that calling in the first place in :
var formidable = require("formidable");
I think you have a typo...
var fomidable = require("formidable");
Should probably be:
var formidable = require("formidable");
Hence the formidable is not defined... you defined it as fomidable.
I'm new to node Js, I've build a really simple server that send me back a zip file I request. It's all working but after some request a crash occur and i visualize this message on the terminal :
FATAL ERROR: node::smalloc::Alloc(v8::Handle, size_t, v8::ExternalArrayType) Out Of Memory
var http = require('http');
var url = require('url');
var fs = require('fs');
var port = 1337;
// create http server
var server = http.createServer(function (request, response) {
var path = require('url').parse(request.url, true);
console.log('requested ' + path.pathname);
//get zipped resoures
if (path.pathname == '/getzip') {
console.log(request.url);
var queryData = url.parse(request.url, true).query;
if (queryData.name) {
var filename = queryData.name;
//open corrisponding file
var zipFile = fs.readFileSync('packets/' + filename);
response.writeHead(200, {
'Content-Type': 'application/x-zip',
'Content-disposition': 'attachment; filename=data.zip'
});
//send file in response
response.end(zipFile);
}
else {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('{error = "bad url"}');
}
}
}).listen(port);
server.timeout = 1000000;
Do you have any idea of what it can be? this code looks so simple.
Instead of reading the entire file into memory, you should leverage streams for this:
response.writeHead(200, {
'Content-Type' : 'application/x-zip',
'Content-disposition' : 'attachment; filename=data.zip'
});
fs.createReadStream('packets/' + filename).pipe(response);
I've been following this tutorial for an introduction on nodejs, but I'm having trouble returning something with response.write().
My server.js code works fine in returning "hello world" when I go to domain:8001, but navigating to domain:8001/socket.html returns a blank screen.
I've used console.log to check that the code to write "socket is here." is being executed, but I'm not sure why it isn't doing anything.
server.js:
var http = require("http");
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
console.log(__dirname);
console.log(path);
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("socket is here.");
}
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404");
break;
}
response.end();
});
server.listen(8001);
var io = require('socket.io').listen(server);
socket.html: (though it shouldn't matter what is contained in it)
<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>
You're ending the response before waiting for fs.readFile() to complete. Try this:
var http = require("http");
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(request, response){
console.log('Connection');
var path = url.parse(request.url).pathname;
console.log(__dirname);
console.log(path);
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("socket is here.");
}
response.end();
});
return;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404");
break;
}
response.end();
});
server.listen(8001);
var io = require('socket.io').listen(server);
Also, doing fs.readFile(__dirname + path, ...); is potentially dangerous because someone could send a request like /../../../../../../etc/passwd. What you should do there instead is use the path module to resolve/normalize __dirname + path to an absolute path, and then ensure that that absolute path starts with the absolute path of your public directory.
hello h have the next code and i like to know how to detect between an ajax request to a normal request? without express.
var http = require('http');
var fs = require('fs');
var path = require('path');
var url = require('url');
http.createServer(function (request, response) {
console.log('request starting...');
console.log("request.url = " + request.url);
console.log("url = "+ url);
response.setHeader('content-Type','application/json');
var filePath = '.' + request.url;
if (filePath == './')
filePath = './index.html';
var extname = path.extname(filePath);
var contentType = 'text/html';
switch (extname)
{
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
}
fs.exists(filePath, function(exists) {
if (exists)
{
fs.readFile(filePath, function(error, content) {
if (error)
{
response.writeHead(500);
response.end();
}
else
{
console.log("contentType = "+contentType);
response.writeHead(200, { 'content-Type': contentType });
response.end(content, 'utf-8');
}
});
}
else
{
response.writeHead(404);
response.end();
}
});
}).listen(8081);
console.log('Server running at http://localhost:8081/');
in the client side i send an ajax request but i ask from the browser request to.
You can check request.headers if it contains HTTP_X_REQUESTED_WITH.
If HTTP_X_REQUESTED_WITH has a value of XMLHttpRequest then it is an ajax request.
Example:
if (request.headers["x-requested-with"] == 'XMLHttpRequest') {
//is ajax request
}
I came across this question and I know it's old but in case someone needs the answer and the idea behind it.
Usually, on the client side, when you make an AJAX request you add a key and value that describe the content i.e: 'content type':'application/json'
So simply, on the server side, you can test the header if it contains application/json as the content type then you are safe to say it's an ajax request.
req.headers['content-type'] == 'application/json'