I followed this tutorial (http://www.hongkiat.com/blog/node-js-server-side-javascript/) and when running the next to last script (for creating a static server) the command prompt says "Server running on port 8080", but when trying to access it at localhost:8080 I just get a webpage is unavailable error.
I have made an rule in the firewall to allow access to 8080 as well.
What could be causing this? Should i be trying to access the page from another address?
When I try to access the page i get the following error message in cmd:
C:\Users\id122302\Documents\test.js:11
path.exists(full_path,function(exists)
^
TypeError: undefined is not a function
at Server.<anonymous> (C:\Users\id122302\Documents\test.js:11:7)
at Server.emit (events.js:110:17)
at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:491:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at Socket.socketOnData (_http_server.js:343:22)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
at Socket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:538:20)
This is my code:
var sys = require("sys");
my_http = require("http");
path = require("path");
url = require("url");
filesys = require("fs");
//Create Server
my_http.createServer(function(request,response)
{
var my_path = url.parse(request.url).pathname;
var full_path = path.join(process.cwd(),my_path);
path.exists(full_path,function(exists)
{
if (!exists)
{
response.writeHeader(404, {"Content-Type":"text/plain"});
response.write("404 Not Found\n");
response.end();
}
else
{
filesys.readFile(full_path, "binary", function(err,file)
{
if (err)
{
response.writeHeader(500,{"Content-Type":"text/plain"});
response.write(err + "\n");
response.end();
}
else
{
response.writeHeader(200);
response.write(file,"binary");
response.end();
}
});
}
});
}).listen(8080);
console.log("Server Running on 8080");
Your server shows an exception and a line number => go for that place !
As observed by #maniacnero, there's no more such thing as path.exists in the API. There's an fs.exists but it's been deprecated, to avoid abusive usage in node's concurrent context.
The feared scenario would be :
you check asynchronously if a file exists.
some other routine deletes/renames it in the meanwhile, or something else on the server does.
you think that the file exists so you try to open it and confidently don't handle the error case.
So the lessons learnt here are :
do things atomically
always deal with failures right away
Provided you stick to this discipline, there's no need for such thing as fs.exists. Here's a modified version of your code :
var sys = require("sys");
var http = require("http");
var path = require("path");
var url = require("url");
var fs = require("fs");
var port = 8080;
http.createServer(function(request,response) {
var my_path = url.parse(request.url).pathname;
var full_path = path.join(process.cwd(),my_path);
fs.readFile(full_path, function(err, file) {
if (err) {
response.writeHeader(404, {"Content-Type":"text/plain"});
response.write("404 Not Found\n");
response.end();
} else {
response.writeHeader(200);
response.write(file);
response.end();
}
});
}).listen(port);
console.log("Server Running on " + port);
I also removed those "binary" thingys, that are way outdated and not documented in the API either !
Playing around with sample code is a nice way to learn, but only if you don't do it blindly. ;) Especially in a weakly typed language building on a fast changing API and where myriads of tutorials have been written by utter beginners. This is your friend : https://nodejs.org/api/
Related
I am using nodejs with mqlight to run a sample code which is provided by https://www.npmjs.com/package/mqlight.
I am using nodejs 5.5.0 and npm version is 3.3.12.
I installed mqlight using npm install mqlight.
var mqlight = require('mqlight');
var recvClient = mqlight.createClient({service: 'amqp://localhost'});
var topicPattern = 'public';
recvClient.on('started', function() {
recvClient.subscribe(topicPattern);
recvClient.on('message', function(data, delivery) {
console.log('Recv: %s', data);
});
});
var sendClient = mqlight.createClient({service: 'amqp://localhost'});
var topic = 'public';
sendClient.on('started', function() {
sendClient.send(topic, 'Hello World!', function (err, data) {
console.log('Sent: %s', data);
sendClient.stop();
});
});
While I am running above code I got below error.
E:\nodejs>node mqtest.js
events.js:154
throw er; // Unhandled 'error' event
^
NetworkError: CONNECTION ERROR (localhost:5672): Connect failure: The remote co
mputer refused the network connection.
at Socket.connError (E:\nodejs\node_modules\mqlight\mqlight.js:1437:19)
at emitOne (events.js:90:13)
at Socket.emit (events.js:182:7)
at emitErrorNT (net.js:1255:8)
at nextTickCallbackWith2Args (node.js:474:9)
at process._tickCallback (node.js:388:17)
Please help to solve this problem. I am using window 7 64 bit os.
Are you sure the service amqp is running? You can follow the below script to start amqp service.
START SERVICE(SYSTEM.AMQP.SERVICE)
START CHANNEL(SYSTEM.DEF.AMQP)
REFRESH SECURITY TYPE(CONNAUTH)
DISPLAY CHSTATUS(SYSTEM.DEF.AMQP) CHLTYPE(AMQP)
We are supposed to create a simple http node server that should respond to a root-url request with a file called index.html. Do not use ExpressJS. Code should have error checking and at least one callback. Put five or more html elements in your index.html. One of the elements should be a link to an external page.
This is the code I have:
var http = require("http");
var fs = require('fs');
var index = fs.readFileSync('index.html');
var server = http.createServer(function(request, response) {
fs.exists(index, function(exists) {
try {
if(exists) {
response.writeHead(200, {"Content-Type": "text/html"});
response.write("<html>");
response.write("<head>");
response.write("<title>Hello World!</title>");
response.write("</head>");
response.write("<body>");
response.write("<div>");
response.write("Hello World!");
response.write("</div>");
response.write("<a href='http://www.google.com' target='_blank'>Google</a>")
response.write("</body>");
response.write("</html>");
} else {
response.writeHead(500);
}
} finally {
response.end(index);
}
});
});
server.listen(80);
console.log("Server is listening");
And I am getting this binding error:
Server is listening
fs.js:166
binding.stat(pathModule._makeLong(path), cb);
^
TypeError: path must be a string
at Object.fs.exists (fs.js:166:11)
at Server.<anonymous> (/Users/rahulsharma/Desktop/server.js:8:4)
at Server.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2112:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
at Socket.socket.ondata (http.js:1970:22)
at TCP.onread (net.js:527:27)
Any thoughts?
Replacing the index variable with 'index.html' will do the job but
please Do NOT use fs.exists , read its API doc
http://nodejs.org/api/fs.html#fs_fs_exists_path_callback
Place the index.html with the .js file. Put all the html in that file.
var http = require("http");
var fs = require('fs');
var server = http.createServer(function(req, res) {
fs.readFile("index.html",function(err,content){
if(err){
throw err;
console.log("Error reading index file.");
res.send("Aw snap!");
}
else{
res.writeHead(200,{"Content-type":"text/HTML"});
res.end(content,"UTF-8");
}
});
});
server.listen(80);
According to you stack trace the error is inside this line:
fs.exists(index, function(exists)
What you pass to this function(which checks if given file exists) is actually content of the file. What you should pass as first argument is probably "index.html" instead of index variable
You are trying to call fs.exists which expects a string path and you are giving it a filehandler index.
That's why the error is:
path must be a string
Either try using the string "index.html" and do not read it sync there. Do it async in the exists callback
fs.exists("index.htm", function(){ fs.readFile("index.htm")
I've been trying this for a while, but I keep getting the error:
Error: Command failed: Invalid Parameter - /images
I installed ImageMagick and the gm package, so that's definitely not the problem.
gm(imageLocation)
.resize(100) // use your own width and height
.write('here.jpg', function (err) {
if (!err) console.log(' hooray! ');
else console.log(err);
});
imageLocation being ./images/3.jpg. Why does this error keep happening? I looked at the documentation
I'm on a Windows 32 bit machine. My server is supposed to get an image from a folder, resize it, and then display it. It seems like I have to write the resized photo and then display that, but the writing process always errors out and the image ends up being empty.
If there's a way to skip the writing part and just displaying the photo directly, that would be awesome too.
Thanks!
URL Query I used: http://localhost:8123/images/3.jpg
Complete code:
var querystring = require('querystring'); //used for parsing parts of urls
url = require('url');
http = require('http');
fs = require('fs');
gm = require('gm').subClass({ imageMagick: true });;
var server = http.createServer();
server.on('request', function(request, response){
var parsed_url = url.parse(request.url, true); //true gets the query as well
imageLocation = '.' + parsed_url.pathname;
gm(imageLocation)
.resize(100) // use your own width and height
.write('here.jpg', function (err) {
if (!err) console.log(' hooray! ');
else console.log(err);
});
if (getImage('here.jpg', response)){
//image is displayed
}
else{
respond404(parsed_url.pathname, response);
}
})
function respond404(path, response){
respond(404, "The requested path " + path + " was not found", response)
}
function getImage(location, response)
{
try{
var img = fs.readFileSync(location);
response.writeHead(200, {'Content-Type':'image/jpg'}); //parse this end
response.end(img, 'binary');
return true;
}catch(e){
return false;
}
}
server.listen(8123);
The answer Svbaker put can be used in Linux (maybe Mac as well?)
For Windows I got it to work by opening the command line in administrator mode and starting my server there.
I was able to get your code to work by changing how you required gm as follows:
var gm = require('gm');
I also had to remember to execute node with the correct permissions in my case:
sudo node server.js
I would like to load a webpage in response to a request for a path,I have figured it out till here:
var http=require('http');
var mysql=require('./mysql');
var fs=require('fs');
var app=http.createServer();
app.listen(8000);
app.on('request',function(req,res){
var _path=req.url;
if(path==='/')
{ res.writeHead(200,{'Content-Type':'text/plain'});
res.end('Hello World \n');
}
if(path==='/demo')
{
//this is bad,we could use streams to improve this(although this is non-blocking too)
fs.readFile('../maps/google_maps.html',function(err,contents){
if(err)
{
console.log('did not work');
res.writeHead(500);
}
else
{
res.setHeader("Content-Length", contents.length);
res.setHeader("Content-Type", mimeType);
res.statusCode = 200;
res.write(contents);
}
res.end();
});
}
});
Server does not work for /demo path,it throws the error:
{ [Error: ENOENT, open '../maps/google_maps.html'] errno: 34, code: 'ENOENT', path: '../maps/google_maps.html' }
var _path=req.url;
if(path==='/')
you create _path but then compare path, which is always undefined
change it to var path=req.url;
error:
ENOENT means file not found
../maps/google_maps.html is a path relative to where you're calling node from, so make sure file exists, or specify full path
To make a path relative to the script, you must use the __dirname variable.
__dirname + '/path/to/file'
You should better use Express.js along with Jade which is a templating engine for Node.js. You can easily render html pages to client and serve static content
I have a node js server, and a html/javascript client.
I simply want to allow the client to send a json-string to the node.js server, the server process's that string and returns a result string back to the client.
I started by setting up the html-client to call like so :
var msg =
{
type: "message",
text: "Hello"
};
function CallWebSocket()
{
var socket = new WebSocket("ws://127.0.0.1:8080","test");
socket.onopen = function (event)
{
alert(JSON.stringify(msg));
socket.send(JSON.stringify(msg));
};
socket.onmessage = function(event)
{
alert(event.data);
}
}
and node.js :
var net = require('net');
var server = net.createServer(function(socket)
{
// do what you need
socket.setEncoding("utf8");
socket.on('data', function(data)
{
var jsonData = JSON.parse(data);
socket.write(jsonData.text);
socket.end();
process.exit(0);
});
});
server.listen(8080);
but on the server I get this error :
undefined:1
``GET / HTTP/1.1
^
SyntaxError: Unexpected token G
at Object.parse (native)
at Socket.<anonymous> (/home/jay/projects/nodejs/test/json-server.js:8:23)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:746:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:526:21)
Any help is much appreciated.
UPDATE
The updated server code :
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
This solved my problem and I am now getting the message back.
A websocket is not a plain TCP socket. That is basically the core of your problem.
The websocket protocol looks like a modified HTTP protocol that allows two way communication using a single (TCP) socket. Read the RFC for more info on how the websocket protocol actually works: https://www.rfc-editor.org/rfc/rfc6455#section-1.2
You have two options if you want to use websockets with node servers:
Read the RFC and write a function to handle the websocket protocol so you can pass that function to socket.on.
Use a websocket server module that someone else have written. Go to npm and search for "websocket server" or google "websocket server npm". There are lots of modules out there. Pick one you like best.
There is a third alternative. Use socket.io. Socket.io is a library that communicates between client and server using websocket if possible (preferred) but is able to degrade to other transports such as Flash and ajax on older browsers.