Here is my first file named serverpaths.js
var http = require("http");
var url = require("url");
function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
Here is my second file named router.js
function route(pathname) {
console.log("About to route a request for " + pathname);
}
exports.route = route;
Here is my third file named index1.js
var server = require("./serverpaths");
var router = require("./router");
server.start(router.route);
The output should be
Server has started
Request for /foo received.
About to route a request for /foo
But I am getting the output
Server has started
Request for /foo received
I don't know why I am not getting the output from router i.e. About to route a request for /foo.
You need call the function that you are passing through to your start function at some point.
var http = require("http");
var url = require("url");
function start(route) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
route(pathname);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
Related
I am new with Node.js, and I am trying to create an HTTP server, but for some reason, when I try to put the router for purchase URL request, it doesn't work.
My code :
Server.js
var url = require("url");
var http = require("http");
function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request received.");
route(pathname);
response.writeHead(200, {"Content-Type" : "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started;");
}
exports.start = start;
Index.js
var server = require("./server");
var router = require("./router");
server.start(router.route);
Router.js
function route(pathname) {
console.log("About to route a request for " + pathname);
}
exports.route = route;
When trying to start the server through the Node.js, it says the follow error :
route is not defined
route(pathname);
How can I make this work ?
You're passing the route to the start function but a parameter isn't defined, you need to add one.
function start(route) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request received.");
route(pathname);
response.writeHead(200, {
"Content-Type": "text/plain"
});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started;");
}
I have the following code:
server.js:
var http = require("http");
function start() {
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, { "Content-Type": "text/plain" });
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
index.js:
var server = require('./server');
server.start();
I try to turn the server.js into a revealing module pattern:
var http = require("http");
var server = function() {
function start() {
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, { "Content-Type": "text/plain" });
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
return {
start: start
};
}();
but I get an error: TypeError: server.start is not a function
What mistake(s) am I making?
Thanks.
You forgot to export your module
exports = server;
I tried to follow an example on the web for creating a NodeJS server and router, but have ran into problems. What follows is primarily the example with a bit of other code.
Index.js
var server = require("./server");
var router = require("./router");
server.start(router.route);'
Router.js
var fs = require("fs");
function route(filename) {
fs.readFile(filename, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
console.log("About to route a request for " + filename);
data = JSON.parse(data);
})
}
exports.route = route;
Server.js
var http = require('http');
var url = require("url");
function start(route) {
function onRequest(request, response) {
var filename = request.url.substr(1);
// call for specific json file here
if (filename == "favicon.ico") {
response.writeHead(200, {'Content-Type': 'image/x-icon'} );
response.end();
console.log('favicon requested');
return;
}
else {
filename += ".json";
console.log("Request for " + filename + " received.");
response.writeHead(200, { 'Content-Type': 'application/json', "Access-Control-Allow-Origin":"*" });
response.write("" + route(filename),0,4);
response.end();
}
}
http.createServer(onRequest).listen(8124);
}
exports.start = start;
console.log('Server running at http://127.0.0.1:8124/');
The question I have is, among others, how does the route command work?
What I get when I browse to the server is 'undefined'. How do I get the actual json from the Router?
I tried: var result = route(filename); but that failed badly.
In essence, how to get the data from the router and write it to the response. If you haven't guessed, javascript and NodeJS is rather new to me.
Any pointers would be greatly appreciated.
Thank you.
Your route function has an async method, fs.readFile. You'll need to pass in a callback to the route function, so that it can return the data properly. Otherwise, route will return immediately with no data (since it's async) regardless if you have a return statement inside readFile.
router.js
function route(filename, callback) {
fs.readFile(filename, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
console.log("About to route a request for " + filename);
data = JSON.parse(data);
callback(data); // Call this function after the data is grabbed.
})
}
server.js portion:
response.writeHead(200, { 'Content-Type': 'application/json', "Access-Control-Allow-Origin":"*" });
route(filename, function (data) {
response.write("" + JSON.stringify(data),0,4);
response.end();
});
I have a service called "localhost:3000/returnStat" that should take a file path as parameter. For example '/BackupFolder/toto/tata/titi/myfile.txt'.
How can I test this service on my browser?
How can I format this request using Express for instance?
exports.returnStat = function(req, res) {
var fs = require('fs');
var neededstats = [];
var p = __dirname + '/' + req.params.filepath;
fs.stat(p, function(err, stats) {
if (err) {
throw err;
}
neededstats.push(stats.mtime);
neededstats.push(stats.size);
res.send(neededstats);
});
};
var http = require('http');
var url = require('url');
var fs = require('fs');
var neededstats = [];
http.createServer(function(req, res) {
if (req.url == '/index.html' || req.url == '/') {
fs.readFile('./index.html', function(err, data) {
res.end(data);
});
} else {
var p = __dirname + '/' + req.params.filepath;
fs.stat(p, function(err, stats) {
if (err) {
throw err;
}
neededstats.push(stats.mtime);
neededstats.push(stats.size);
res.send(neededstats);
});
}
}).listen(8080, '0.0.0.0');
console.log('Server running.');
I have not tested your code but other things works
If you want to get the path info from request url
var url_parts = url.parse(req.url);
console.log(url_parts);
console.log(url_parts.pathname);
1.If you are getting the URL parameters still not able to read the file just correct your file path in my example. If you place index.html in same directory as server code it would work...
2.if you have big folder structure that you want to host using node then I would advise you to use some framework like expressjs
If you want raw solution to file path
var http = require("http");
var url = require("url");
function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
source : http://www.nodebeginner.org/
simply call req.url. that should do the work. you'll get something like /something?bla=foo
You can use this in app.js file .
var apiurl = express.Router();
apiurl.use(function(req, res, next) {
var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
next();
});
app.use('/', apiurl);
req.protocol + '://' + req.get('host') + req.originalUrl
or
req.protocol + '://' + req.headers.host + req.originalUrl // I like this one as it survives from proxy server, getting the original host name
Based on #epegzz suggestion for the regex.
( url ) => {
return url.match('^[^?]*')[0].split('/').slice(1)
}
returns an array with paths.
A more modern solution that utilises the URL WebAPI:
(req, res) => {
const { pathname } = new URL(req.url || '', `https://${req.headers.host}`)
}
I've used this const { pathname } = req?._parsedUrl || {}; and it worked for me
Combining solutions above when using express request:
let url=url.parse(req.originalUrl);
let page = url.parse(uri).path?url.parse(uri).path.match('^[^?]*')[0].split('/').slice(1)[0] : '';
this will handle all cases like
localhost/page
localhost:3000/page/
/page?item_id=1
localhost:3000/
localhost/
etc. Some examples:
> urls
[ 'http://localhost/page',
'http://localhost:3000/page/',
'http://localhost/page?item_id=1',
'http://localhost/',
'http://localhost:3000/',
'http://localhost/',
'http://localhost:3000/page#item_id=2',
'http://localhost:3000/page?item_id=2#3',
'http://localhost',
'http://localhost:3000' ]
> urls.map(uri => url.parse(uri).path?url.parse(uri).path.match('^[^?]*')[0].split('/').slice(1)[0] : '' )
[ 'page', 'page', 'page', '', '', '', 'page', 'page', '', '' ]
I've just managed to connect to a server script with socket.io, so I'm happy about that. I'm less happy though about the weird behavior my script generates: I send one emit to the server script on a buttonclick, and the server test script sends back a message 6x to the console log. Googling this problem description gets ideas about spotty, repeating connections, but I don't think that's it.
Anyway, here's the client app.js:
var commentapp={
init: function(){
var commentapp=this;
commentapp.btn_api=$('#btn_api');
commentapp.btn_api.click(this.get_comment_data);
},
get_comment_data: function(btn_event){
var commentapp=this;
console.log('trying to connect');
commentapp.socket=io.connect('http://localhost:8080');
commentapp.socket.on('connect', function() {
commentapp.socket.emit('btn_api_call');
}); //commentapp.socket.on 'connect',
commentapp.socket.on('serverMessage', function(content){
console.log(content);
}
); //commentapp.socket.on('serverMessage'
}
};
$(function() {
commentapp.init();
});
The server script is as follows:
var httpd = require("http").createServer(handler);
var io=require('/Users/user/Virtualenvs/node_modules/socket.io/lib/socket.io').listen(httpd);
var fs = require('fs');
var url = require("url");
var path = require("path");
var port = process.argv[2] || 8080;
httpd.listen(parseInt(port, 10));
function handler (request, response) {
var uri = url.parse(request.url).pathname,
filename = path.join(process.cwd(), uri);
console.log(uri);
path.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return; //these returns get you out of the function I think
}
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
response.writeHead(200);
response.write(file, "binary"); //otherwise here's where the file gets finally served
response.end();
}); //fs.readFile
}); //path.exists
io.sockets.on('connection',function(socket) {
socket.on('btn_api_call', function() {
socket.emit('serverMessage', 'Server heard you.');
});
});
};
console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown");
Both of these are cannibalized from https://github.com/accbel/nodejs-socketio-example and Pedro Teixeira's book.
So if I click the button to generate the 'btn_api_call'emit, the console log will say "'Server heard you.'" 6x. Hopefully this is a rookie mistake easily set straight.
Thanks for your help!
This is likely due to having your registration for connections inside of a route handler.
Each time a request comes in that is handled by that route, the code is adding a new listener for connections.
You likely have a similar problem in your client - connecting each time the button is clicked.
Move your connection listener outside the route like this:
function handler (request, response) {
var uri = url.parse(request.url).pathname,
filename = path.join(process.cwd(), uri);
console.log(uri);
path.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return; //these returns get you out of the function I think
}
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
response.writeHead(200);
response.write(file, "binary"); //otherwise here's where the file gets finally served
response.end();
}); //fs.readFile
}); //path.exists
};
io.sockets.on('connection',function(socket) {
socket.on('btn_api_call', function() {
socket.emit('serverMessage', 'Server heard you.');
});
});
On the client move the connect logic to init - something like:
var commentapp={
init: function(){
var commentapp=this;
commentapp.btn_api=$('#btn_api');
commentapp.btn_api.click(this.get_comment_data);
console.log('trying to connect');
commentapp.socket=io.connect('http://localhost:8080');
commentapp.socket.on('connect', function() {
commentapp.socket.emit('btn_api_call');
}); //commentapp.socket.on 'connect',
commentapp.socket.on('serverMessage', function(content){
console.log(content);
}
); //commentapp.socket.on('serverMessage'
},
get_comment_data: function(btn_event){
var commentapp=this;
commentapp.socket.emit('btn_api_call');
}
};