I've been having this issue where for some reason the Express route doesn't see my root get function. I've declared my app.js this way:
var index = require('./app/routes/index');
var app = express();
app.use('/', index);
Then in my index.js I have my definition this way:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
console.log('Enter root.');
});
router.get('/something', function(req, res, next) {
console.log('Enter something.');
});
Express routes into '/something' just fine, but couldn't see '/'. Anybody have an idea why it doesn't work? Thanks.
Modified based on new info:
If you're getting a 304 status back in the browser, that's because the browser has cached the GET request and the server is telling the browser that the page has not been changed so the browser can just use the cached copy.
You can make the page uncacheable by changing the headers the server sends with the request.
See Cache Control for Dynamic Data Express.JS and NodeJS/express: Cache and 304 status code and Nodejs Express framework caching for more info.
You show no exports in index.js so this line:
var index = require('./app/routes/index');
does not accomplish anything. index is an empty object and thus this:
app.use('/', index);
doesn't do anything and, in fact, may even cause an error.
Perhaps what you want is this:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
console.log('Enter root.');
});
router.get('/something', function(req, res, next) {
console.log('Enter something.');
});
// export your router
module.exports = router;
Then, index in your other file will be the router.
Related
I m still trying to learn NodeJs but I came across this path thing I encountered in Express. When I create an app using Express I noticed that in app.js I have these lines of code var index = require('./routes/index');
var users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
And in users.js I already have configured
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
I don t really understand why is it in users.js router.get('/') instead of router.get('/users') as it is specified in app.js? Can someone explain a bit what s going on in this case?
As far as I understand in app.js it says whenever someone tries to access the specified route('/users') lets say localhost:3000/users in the browser, let the file required in users variable handle it.
If you are working with routes the express app is automatically . Here is an example from the express.js website:
In our router file we have:
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
Then in our main file were we have our server etc we load in the router:
var birds = require('./birds')
// ...
app.use('/birds', birds)
These routes in the router app are only accessed when there is a request to to /birds url. All the routes in the router are now automatically staring with /birds
So this code in the express router:
// im code in the birds router
router.get('/about', function (req, res) {
res.send('About birds')
})
Is only executed when someone makes a get request to the /birds/about url.
More information in the official express.js docs
I would just like to point out what I have learnt today after some frustration, and maybe somebody can elaborate as to why this happens. Anyway, if, like me, you want to use '/users' for all user routes or '/admin' for all administrator routes then, as WillemvanderVeen mentioned above, you need to add the following code to your main app.js file
var users = require('./routes/users')
app.use('/users', users)
However, one thing which was not mentioned is that the order with which you declare your 'app.use('/users', users)' in app.js is important. For example, you would have two route handling files as so:
/routes/index.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => { res.render('index') });
/routes/users.js
const express = require('express'); const router = express.Router();
router.get('/', (req, res) => { res.send('users route') })
You would then require them in your main app.js file as so:
app.js
const express = require('express');
const app = express();
const index = require('./routes/index');
const users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
and you would expect that when you hit the '/users' route that you would receive the res.send('users route') page.
This did not work for me, and I struggled to find any solution until recently, which is why I am now commenting to help you.
Instead, I swapped the app.use() declarations in app.js around like so and it worked:
app.js
const express = require('express');
const app = express();
const index = require('./routes/index');
const users = require('./routes/users');
app.use('/users', users);
app.use('/', index);
Now when I hit '/users' I see the 'users route' message. Hope this helped.
To answer your question though, when you configure the route handler in app.js as users, then you are requiring a router file (./routes/users) to handle all requests from that file and sending them to the URL /users first. So if you do the following:
/routes/users.js
router.get('/dashboard', (req, res) => {
// get user data based on id and render it
res.render('dashboard')
});
then whenever user is logged in and goes to dashboard, the URL will be /users/dashboard.
Important from my app.js file:
var express = require('express');
var profile = require('./controllers/profile-controller'); //require my controller (profile-controller.js)
app.use(express.static(path.join(__dirname, 'public')));
app.use('/user', profile);
When I go to 'mysite.com/user' - it works fine, but when I go to 'mysite.com/user/user1', my CSS and images ain't loading. Here is my controller file:
var express = require('express');
var router = express.Router();
// route for www.mysite.com/user
router.get('/', function(req, res, next) {
res.render('profile',{ title: 'Profile' });
});
// route for www.mysite.com/user/user1
router.get('/:id([A-Za-z0-9_]{5})', function(req, res, next) {
var id = req.params.id;
res.render('profile',{ title: 'Profile' });
});
module.exports = router;
Console gives me that:
So why I have the same route for both pages, but one of them working well, but second gives 404 for static files?
In your index.hbs file, you have src="images/wow.png", which is a relative path to your image resource. So when you go to /user/user1, it just adds the /user to your image resource path.
Instead of src="images/wow.png" try putting src="/public/images/wow.png" or src="/images/wow.png".
I have trouble implementing route mounting in express.js 4.13.3.
When I first install it, by default created in the app.js
var users = require('./routes/users');//get the "users" route
app.use('/users', users);//mount to "/users"
and the users.js route is like
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('respond with a resource');
});
module.exports = router;
Does not need to define router.get('/users'... because mounting took care of that in the app.js file.
But
When I try to do the same thing
in app.js I set
var upload = require('./routes/upload');
app.get('/upload', upload);//mounting (?)
the upload.js route is
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('upload', {title: 'Photo upload'});
});
module.exports = router;
When I access localhost/users I get 404 error. The only way to fix this , is to define in the upload.js router, this router.get('/upload' instead of this router.get('/'. But that would not be mounting.
The difference I see is that the default code uses app.use('/users', users); and my code uses app.get('/upload', upload);. Is the verb (use/get) the only difference that causes the 404? And if so, why? Or is it something else?
Thanks
You are totally correct that the problem is caused because these to functions work differently. Below are the official API specifications for the functions.
app.use is for mounting a middleware
app.get is for defining (only) one route for a HTTP GET request
This example shows a middleware function mounted on the /user/:id path. The function is executed for any type of HTTP request on the /user/:id path.
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
This example shows a route and its handler function (middleware system). The function handles GET requests to the /user/:id path.
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
I am using expressjs and I want get a request object comes form this url
http://www.thedomain.com/membername/category/item?item=abc
in server side. I am trying to use
// app.js
var express = require('express');
var routes = require('./routes/index');
var app = express();
app.use('/*', routes);
In './routes/index':
//'./routes/index''./routes/index'
var express = require('express');
var config = require('../config');
var router = express.Router();
var url = require('url');
/* GET category page. */
router.get('/category', function(req, res, next) {
console.log(' pathname: ',url.parse(req.url).pathname)
res.render('index', {
title: url.parse(req.url).pathname
});
});
Actually, I have no way to get value of membername
I want to know how could I get value of membername before process item value in query string in the category router. I also want to know how to write a regex that accept all value of membername for the router which stay on the front of the category router as a pre-process module.
Thank for all your comment and answer
req.get('/:memberName/category/item', function(req, res, next) {
// do whatever you want with req.prams.memberName here...
next();
});
req.get('/:memberName/category/item', function(req, res, next) {
// now do whatever you want with req.query.item here...
});
Since you suggest you want to restrict only to letters and numbers (and perhaps _ too), use a regular expression:
req.get('/\w+/category/item', function(req, res, next) {
// Access membername via req.params[0]
});
I've had bad luck with Express routes and regular expressions, but I believe that problem has been fixed in Express 4.0.
I have a simple express app (version 4.9.0) and I am trying to put my middleware in to external files.
My app.js has:
var middleware = require('./lib/middleware');
app.get('/foo', middleware.configcache);
/lib/middleware contains index.js:
exports.configcache = require('./configcache.js');
/lib/middleware/configcache.js contains:
function configcache(req, res, next) {
console.log("hello world");
next();
}
module.exports = configcache;
When I make a GET request to /foo I get a 404. Can anyone advise?
This is how I use it in one of my apps:
app.js:
var routes = require('./routes/index');
routes/index.js:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', {
title: req.i18n.t("meta.title.index")
});
});
module.exports = router;
I scaffolded this express project with the yeoman express generator: yo express
So the answer to your problem is: Don't call next(), but send an actual response to the browser - when you are using router.get():
function configcache(req, res, next) {
res.send(200, 'hello world');
}
or use router.use like described here: http://expressjs.com/guide/using-middleware.html