Cannot GET /the route Error - javascript

I'm following this tutorial (source code) and added the highlighted code.
// app.js
app.get("/notebooks", function(req, res) {
var client = new Evernote.Client({ token: req.session.oauthAccessToken }),
noteStore = client.getNoteStore();
noteStore.listNotebooks(function(err, noteBooks) {
res.send(err || noteBooks);
});
});
app.get('/importNotes', function (req, res) {
res.send('importNotes');
});
app.get("/notes/:guid", function(req, res) {
var client = new Evernote.Client({ token: req.session.oauthAccessToken }),
noteStore = client.getNoteStore();
noteStore.getNote(req.params.guid, true, true, true, true, function(err, note) {
if (!err) {
note.content = ENML.HTMLOfENML(note.content, note.resources);
}
res.send(err || note);
});
});
another attempt:
app.get('/importNotes', function (req, res) {
res.render('importNotes', {});
});
I created importNotes.html near to index.html.
After starting the server with node app.js
I'm getting an error stating Cannot GET /importNotes
when I access localhost:3000/importNotes
I plan to use this page to add additional features after I deal with this issue (import the notes from the special txt file).
What I'm doing wrong and how I can correct it?
How to define correctly the needed routes ?

This is Steve - thanks for trying out the code !
If you use this code :
app.get('/importNotes', function (req, res) {
res.send('importNotes');
});
Then I would expect the server will send back to the browser the string "importNotes". Perhaps if you have a file called "importNotes" there is some confusion.
If you want to create a file called importNotes.html - then just put it into the "public" folder. It will then be accessible via localhost:3000/importNotes.html
The line :
app.use(express.static(__dirname + "/public"));
Tells Express to serve the contents of the "public" folder at the root level of your application, so any files you put in that folder should be GETable. e.g.
/public
index.html
steve.html
localhost:3000/steve.html

Related

node.js express and regular expressions

Hi friends I am working with node.js and express. I have some endpoints and inside there are dynamic files every file have a name of an IP for example services/192.168.0.1.html, service/192.168.0.11.html, service/192.168.0.15 etc. So I want to make a dynamic route like this code:
app.get('/endpointej/**REGEXP**forIP.html', (req, res) => {
var ruta = {
root: path.join(__dirname + 'endpoint/)
}
res.sendFile("IPfiledinamic.html",ruta)
});
Can some one help me out please ?
Regards
You can use something like
// route is for GET /test/1.1.1.1.html, but not for GET /test/1.2.3.html
app.get(/test\/([0-9]{1,3}\.){3}[0-9]{1,3}\.html/, (req, res) => {
const ipRegex = /^\/test\/((?:[0-9]{1,3}\.){3}[0-9]{1,3})\.html$/
// do more here...
res.status(200).send(`matches, ${req.url.match(ipRegex)}`)
})

AJAX: Listing out the content of a directory. Unable to resolve URL

I'm trying to display some images contained in a folder, inside a div. I'm using AJAX to do that in a JavaScript file called edit that is one directory away from the index route. I'm using Node.js. The code I have written is as follows.
var folder = "../images/emojies/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
// some code
});
}
});
I get this error:
"GET /images/emojies/ 404"
The weird thing is that when I go to this for example:
"/images/emojies/image.png", It finds the directory with no errors!
It's like it can't find folders but it can find files?
routing code if needed:
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'xx' });
});
/* GET edit page. */
router.get('/edit', function(req, res, next) {
res.render('edit', { title: 'xx' });
});
You could have done something like follows.
var app = require('express')();
var http = require('http').Server(app);
var fs = require('fs');
var clients = 0;
app.get('/images/emojies', function(req, res) {
var path = "public/images/emojies/"; //Could be obtained from req.path however, needs to resolve the path properly.
fs.readdir(path, function(err, items) {
res.send(items); // items is an array
});
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
/images/emojies would be the endpoint that you would contact and you could use your existing AJAX request as follows.
var folder = "/images/emojies";
$.ajax({
url : folder,
success: function (data) {
//Under data, you have a stringified array of the file names.
}
});
The best thing about this method is that it gives you more fine-grained control over the file types and file names that you are going to expose, especially given that you are going to expose a part of your file system.
You can use path module to fix your problem:
https://nodejs.org/api/path.html
I think that it should look like this:
var folder = path.normalize("../images/emojies/");
In Nodejs when you access to folder you have to write folder root with ./ sign.
For example
var folder = "./../images/emojies/";//Firstly you have to write "./" it access to the same folder where your file is then go up another folder
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
// some code
});
}
});

How to break this Node code into different files

I want to put code such as
app.use("/localAssets", express.static(__dirname + '/localAssets'));
app.use("/scripts", express.static(__dirname + '/scripts'));
in a different file, right now it is in the main server file but I do not like that. I also don't like that all the scoket event handling is also in the main server file.
ie
function onSocketConnection(client) {
//player connected
// Listen for client disconnected
client.on("disconnect", onClientDisconnect);
client.on('sendMessage', function (data) {
this.broadcast.emit('message', data);
this.emit('message', { text: data.text});
});
// Listen for new player message
client.on("new player", onNewPlayer);
// Listen for move player message
client.on("move player", onMovePlayer);
client.on("update health", onUpdateHealth);
client.on("attack hits", onHitByAttack);
client.on("meteor cast", onMeteorCast)
};
function onClientDisconnect() {
...
}
Please advise!
Here is the full file I want to sort out:
https://gist.github.com/hassanshaikley/337e5b7b7a8206a54418
Just put anything you want into different files inside of a function like this:
module.exports = function() {
// your code here
};
Then require and call that function, passing in whatever reference it may need, such as app:
// my-file.js
module.exports = function(app) {
// your code here
};
// index.js
require('./path/to/my-file')(app);
Here's a basic example of moving routes into another file:
// index.js
require('./path/to/some-routes')(app);
// some-routes.js
module.exports = function(app) {
app.get('/foo', function(req, res) {
res.send('Hi! This is foo.');
});
app.get('/bar', function(req, res) {
res.send('Hi! This is bar.');
});
app.get('/:me', function(req, res) {
res.send('Hi! This is '+req.params.me);
});
};

node.js and express file uploader

So I am following this tutorial: http://thejackalofjavascript.com/uploading-files-made-fun/
I have followed the steps all the way up to where they create the routes and haven't actually created any views. It says
Thats it we are all done with our server. Restart your server and
navigate to http://localhost:3000/upload. You should see a JSON
response with the empty array of files.
However when I try to run app.js it sits for a few seconds and then just goes back to the command prompt. No errors are given and I am clueless as to how to fix this.
Here is my code in routes/uploadManager.js
var options = {
tmpDir: __dirname + '/../public/uploaded/tmp',
uploadDir: __dirname + '/../public/uploaded/files',
uploadUrl: '/uploaded/files/',
maxPostSize: 11000000000, // 11 GB
minFileSize: 1,
maxFileSize: 10000000000, // 10 GB
acceptFileTypes: /.+/i,
// Files not matched by this regular expression force a download dialog,
// to prevent executing any scripts in the context of the service domain:
inlineFileTypes: /\.(gif|jpe?g|png)/i,
imageTypes: /\.(gif|jpe?g|png)/i,
imageVersions: {
width: 80,
height: 80
},
accessControl: {
allowOrigin: '*',
allowMethods: 'OPTIONS, HEAD, GET, POST, PUT, DELETE',
allowHeaders: 'Content-Type, Content-Range, Content-Disposition'
},
storage : {
type : 'local'
}
};
var uploader = require('blueimp-file-upload-expressjs')(options);
module.exports = function (router) {
router.get('/upload', function (req, res) {
uploader.get(req, res, function (obj) {
res.send(JSON.stringify(obj));
});
});
router.post('/upload', function (req, res) {
uploader.post(req, res, function (obj) {
res.send(JSON.stringify(obj));
});
});
router.delete('/uploaded/files/:name', function (req, res) {
uploader.delete(req, res, function (obj) {
res.send(JSON.stringify(obj));
});
});
return router;
}
I apologize. I was trying to run node app.js when I was supposed to be running node bin/www since this is an express.js app.

how to get request path with express req object

I'm using express + node.js and I have a req object, the request in the browser is /account but when I log req.path I get '/' --- not '/account'.
//auth required or redirect
app.use('/account', function(req, res, next) {
console.log(req.path);
if ( !req.session.user ) {
res.redirect('/login?ref='+req.path);
} else {
next();
}
});
req.path is / when it should be /account ??
After having a bit of a play myself, you should use:
console.log(req.originalUrl)
Here is an example expanded from the documentation, which nicely wraps all you need to know about accessing the paths/URLs in all cases with express:
app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?a=b'
console.dir(req.originalUrl) // '/admin/new?a=b' (WARNING: beware query string)
console.dir(req.baseUrl) // '/admin'
console.dir(req.path) // '/new'
console.dir(req.baseUrl + req.path) // '/admin/new' (full path without query string)
next()
})
Based on: https://expressjs.com/en/api.html#req.originalUrl
Conclusion: As c1moore's answer states, use:
var fullPath = req.baseUrl + req.path;
In some cases you should use:
req.path
This gives you the path, instead of the complete requested URL. For example, if you are only interested in which page the user requested and not all kinds of parameters the url:
/myurl.htm?allkinds&ofparameters=true
req.path will give you:
/myurl.html
UPDATE 8 YEARS LATER:
req.path was already doing exactly same thing that I mentioned here. I don't remember how this answer solved issue and accepted as a correct answer but currently it's not a valid answer. Please ignore this answer. Thanks #mhodges for mentioning this.
Original answer:
If you want to really get only "path" without querystring, you can use url library to parse and get only path part of url.
var url = require('url');
//auth required or redirect
app.use('/account', function(req, res, next) {
var path = url.parse(req.url).pathname;
if ( !req.session.user ) {
res.redirect('/login?ref='+path);
} else {
next();
}
});
This can produce different results when calling directly in base module i.e. main file (e.g. index.js or app.js) vs calling from inside module via app.use() middleware i.e. route file (e.g. routes/users.js).
API call:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
We'll be comparing our outputs against above API call
1) First, we'll see the result from inside module:
We'll be placing our user module inside routes directory, with one route
routes/users.js
const router = (require('express')).Router();
router.get('/profile/:id/:details', (req, res) => {
console.log(req.protocol); // http or https
console.log(req.hostname); // only hostname (abc.com, localhost, etc)
console.log(req.headers.host); // hostname with port number (if any)
console.log(req.header('host')); // <same as above>
console.log(req.route.path); // exact defined route
console.log(req.baseUrl); // base path or group prefix
console.log(req.path); // relative path except path
console.log(req.url); // relative path with query|search params
console.log(req.originalUrl); // baseURL + url
// Full URL
console.log(`${req.protocol}://${req.header('host')}${req.originalUrl}`);
res.sendStatus(200);
});
module.exports = router;
index.js
const app = (require('express'))();
const users = require('./routes/users');
app.use('/api/users', users);
const server = require('http').createServer(app);
server.listen(8000, () => console.log('server listening'));
Output
http ....................................................................................... [protocol]
localhost .............................................................................. [hostname]
localhost:8000 ..................................................................... [headers.host]
localhost:8000 ..................................................................... [header('host')]
/profile/:id/:details ........................................................ [route.path]
/api/users ............................................................................. [baseUrl]
/profile/123/summary .......................................................... [path]
/profile/123/summary?view=grid&leng=en ........................ [url]
/api/users/profile/123/summary?view=grid&leng=en ..... [originalUrl]
Full URL:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
2) Now, directly from main module:
We'll define our route right in the starting file (i.e. app.js or index.js)
index.js
const app = (require('express'))();
app.get('/api/users/profile/:id/:details', (req, res) => {
console.log(req.protocol); // http or https
console.log(req.hostname); // only hostname (abc.com, localhost, etc)
console.log(req.headers.host); // hostname with port number (if any)
console.log(req.header('host')); // <same as above>
console.log(req.route.path); // exact defined route
console.log(req.baseUrl); // base path or group prefix
console.log(req.path); // relative path except path
console.log(req.url); // relative path with query|search params
console.log(req.originalUrl); // baseURL + url
// Full URL
console.log(`${req.protocol}://${req.header('host')}${req.originalUrl}`);
res.sendStatus(200);
});
const server = require('http').createServer(app);
server.listen(8000, () => console.log('server listening'));
Output
http ........................................................................ [protocol]
localhost ............................................................... [hostname]
localhost:8000 ...................................................... [headers.host]
localhost:8000 ...................................................... [header('host')]
/profile/:id/:details ......................................... [route.path]
.............................................................................. [baseUrl]
/profile/123/summary ........................................... [path]
/profile/123/summary?view=grid&leng=en ......... [url]
/profile/123/summary?view=grid&leng=en ......... [originalUrl]
Full URL:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
We can clearly see in above output that the only difference is of baseUrl which is empty string here. So, the originalUrl also changes & looks same as the url
//auth required or redirect
app.use('/account', function(req, res, next) {
console.log(req.path);
if ( !req.session.user ) {
res.redirect('/login?ref='+req.path);
} else {
next();
}
});
req.path is / when it should be /account ??
The reason for this is that Express subtracts the path your handler function is mounted on, which is '/account' in this case.
Why do they do this?
Because it makes it easier to reuse the handler function. You can make a handler function that does different things for req.path === '/' and req.path === '/goodbye' for example:
function sendGreeting(req, res, next) {
res.send(req.path == '/goodbye' ? 'Farewell!' : 'Hello there!')
}
Then you can mount it to multiple endpoints:
app.use('/world', sendGreeting)
app.use('/aliens', sendGreeting)
Giving:
/world ==> Hello there!
/world/goodbye ==> Farewell!
/aliens ==> Hello there!
/aliens/goodbye ==> Farewell!
It should be:
req.url
express 3.1.x
For version 4.x you can now use the req.baseUrl in addition to req.path to get the full path. For example, the OP would now do something like:
//auth required or redirect
app.use('/account', function(req, res, next) {
console.log(req.baseUrl + req.path); // => /account
if(!req.session.user) {
res.redirect('/login?ref=' + encodeURIComponent(req.baseUrl + req.path)); // => /login?ref=%2Faccount
} else {
next();
}
});
req.route.path is working for me
var pool = require('../db');
module.exports.get_plants = function(req, res) {
// to run a query we can acquire a client from the pool,
// run a query on the client, and then return the client to the pool
pool.connect(function(err, client, done) {
if (err) {
return console.error('error fetching client from pool', err);
}
client.query('SELECT * FROM plants', function(err, result) {
//call `done()` to release the client back to the pool
done();
if (err) {
return console.error('error running query', err);
}
console.log('A call to route: %s', req.route.path + '\nRequest type: ' + req.method.toLowerCase());
res.json(result);
});
});
};
after executing I see the following in the console and I get perfect result
in my browser.
Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
For those getting undefined from req.route.path that is correct.
Inside route handler, there's a route.
Inside middleware handlers, there's no route.
When using a middleware in express, your request object has several properties you can use to get the correct path:
req.baseUrl: /api/account
req.originalUrl: /api/account
req._parsedUrl.path: /account
req._parsedUrl.pathname: /account
req._parsedUrl.href: /account
req._parsedUrl._raw: /account
PLEASE NOTE: This applies to middlewares

Categories