I'm working with nodejs and ejs template. I want to set a middleware which will be called only when page loading, not when I send request from code.
Example:
app.use(function(req, res, next){
if(req.session){
console.log("OKAY");
}
next();
});
I want this log appears only on page loading, not when I send request from code like below
$.get( "/users", function( data ) {
console.log(data);
});
How can I do this ?
Thank you
You have a couple options:
In your middleware, you can check req.path to see if it's a path that you should apply the middleware to or not and use an if in your middlware to either just call next() without doing anything or to do whatever the middleware is designed to do.
You can design your routes to that page routes and ajax routes are on separate paths and then design a router for page routes and a router for ajax routes and put the middleware only on the page router.
It will really help you a lot (with either option above) if you design your URLs so it's easy for your server to distinguish whether this is a URL that should or should not have the middleware applied. Usually, the simplest way to do that is to use a known prefix on one or both branches of your URL design. For example, all ajax URLs could start with /api and then you can easily shunt all API calls off to a special router and all other URLs are non-API URLs (probably page URLs).
Here's an example of the separate API router:
// split off all API calls to a separate router
let apiRouter = express.Router();
app.use('/api', apiRouter);
// handle /api/users
apiRouter.get('/users', handleUserAjaxRequest);
// handle all other /api/xxx routes that don't have their own handler
apiRouter.use(function(req, res, next) {
// if /api request not handled by here, then don't allow it to propagate further
// it must be a invalid /api/xxx URL, so do a 404
res.status(404).end();
});
// this won't get called if there's a /api/xxx URL because that will have
// already been handled by the apiRouter
app.use(someMiddleware);
app.get('/somepage', handleSomePageURL);
You could also use a separate router for all your page requests which might make modularity a little cleaner with all the API routes in one module and all the page routes in another module, each exporting their own router.
I'm using JQuery to send request from client and I saw from jfriend00's link that req.xhr returns a Boolean property that is true if the request’s X-Requested-With header field is “XMLHttpRequest”, indicating that the request was issued by a client library such as jQuery.
app.use(function(req, res, next){
if(req.xhr){
console.log("FROM CLIENT LIBRARY");
}
next();
});
Thank you jfriend00
Related
SO i have an express app that I have been building an app that uses a body parser that works with my entire app client side. ( receive post req data )
but app.use(bodyParser.json()); seemed to cause issues with apis which is why i commented it out. now that I dont use it, i cant receive post data from my website.. What should I do so that apis and my website works?
// APP
var app = express();
//app.use(bodyParser.json()); //ISSUE: this is breaks API post //but i need it to recieve MY post req data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(fileUpload());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
A simple kludge would be to define the routes that twilio uses before you activate the bodyParser middleware. Without knowing more about why exactly the bodyparser prevents twilio from working, that's the best I can do.
In generell I alway suggest to not register body parsers globally for all follow up routes, but directly with the route or only locally for one router (path prefix) where it is required.
Moving the routers of twilio before registering the bodyParser for all following routes will also work, but it is less maintainable.
So if you need json data in on specific route, then write it that way:
app.post('/some/route', bodyParser.json(), (req, res, next) => {
// processing of your json
});
The reason why I suggest this is, because the body that is submitted to the server is provided as stream. Whenever you register a middleware that will process the body then it will consume the whole content, and you cannot use any other middleware that will also process the body after that. Using it only for the route where you need this parser eliminates this problem, and allows you to use different body parsers depending on the route.
The larger your project becomes the more likely it is that you come to a situation where you need an other body parsers, then you will be most likely at a point where moving the routes would not work anymore.
This is easy to do with a client side router or JS on the client. But since window is not an object on the server how would one get a query parameter or even read a url from the server? I checked node examples but couldn't find anything that didn't pertain to express js.
My use case is Instagram, It sends me back a code that needs to be read on the server and then I send a http request with that code from the server to retrieve an access token.
Has to be on page load, not load then send to server via client.
Basically I want to retrieve the query of "code" http://localhost:3000/?code=5e04c2e304f24f8b8380c2ec81202139 on the server.
I read the Instagram instruction for authentication, it seems that you are using the Server-side flow. I do not know why you choose this over the Client-side authentication flow which seems to be more appropriate, I think you should re-consider which method to use. Anyway, to answer your question you could use WebApp package to define a server route in Meteor:
WebApp.connectHandlers.use("/", function(req, res, next) {
if (req._parsedUrl.pathname === '/') {
const code = req.query.code;
console.log(code);
// get ACCESS_TOKEN with code
// if you need to redirect user after authorization
// res.writeHead(302, {
// Location: '/route/after/authorization'
// });
// res.end();
}
// comment this if you redirect to another route
next();
});
I would like to send a request to a certain route within express.js directly to 404 if the user is not authenticated.
in my middleware I have the following code:
exports.isAuthenticated = function (req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect("/login");
}
};
what I would like to do instead is to present the user with a 404 page instead. I have configured one globally, but I dont know how I am supposed to skip every chained middleware for a request and send a user to 404 directly.
Thanks for answers :)
okay I got the answer. I have to use
If you need to skip the rest of the middleware from a router
middleware stack, call next('route') to pass on the control to the
next route. Note: next('route') will work only in middleware loaded
using app.VERB() or router.VERB().
according to http://expressjs.com/guide/using-middleware.html and its working
I'm reading the two examples in the Express.js API reference but I don't get them.
Example No. 1
Now suppose you wanted to ignore logging requests for static files, but continue logging routes and middleware defined after logger(). You could simply move static() above it:
app.use(express.static(__dirname + '/public'));
app.use(logger());
// other middleware
How does this cause requests for static files not to be logged? Isn’t all middleware executed (in sequence) for every request?
Example No. 2
Another concrete example would be serving files from multiple directories, giving precedence to "./public" over the others:
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));
I suspect that for e.g. a request like "/js/stuff.js", the first middleware checks if "/public/js/stuff.js" exists. If it does, this middleware handles the request and none of the subsequent middleware is executed (sort-of like an early return). If this path however doesn't exist, this middleware passes the request to the next middleware in line. Is this correct?
Please explain both examples!
Express routes are just a collection of middleware. Every request to the server is passed along the middleware chain.
A middleware function has the signature
function(req, res, next) { }
You can add middleware to the chain with app.use(), as you've seen above.
Each middleware has two choices. It can
Pass the request to the next middleware in the chain, or
End the request chain and send a response
If a middleware fails to do either of these, you'll see your request time out and just "spin" endlessly.
To pass a request along, the middleware must call next(). The third argument passed to a middleware is this next() function. It might have a side effect, like the logger middleware above.
To end a request, the middleware can use one of several methods attached to the res object, such as res.send() or res.end() to send a response back to the requestor. So the express.static middleware has the behavior that, if it finds the requested file, it ends the request chain and sends the file. If it doesn't find the requested file, it passes the request to the next middleware.
I am writing a library for a web service in Node.js. My library needs to handle all HTTP requests with a particular URL prefix (Eg, /_docs/*).
I want people to be able to use my library without changing much of their code.
The API should look something like this:
server = http.createServer(function(req, res) { ... });
...
myLibrary.listen(server, '_docs/');
or
server = new http.Server();
myLibrary.listen(server, '_docs/');
server.on('request', function(req, res) { ... });
If I merely register another event handler on the server object, the user's http request handler will be called on all HTTP requests as well. My code will race with the user's 404 handler.
Socket.io has a similar problem, and they solve it by making their .listen() function move all existing http request handlers into a private array. When HTTP requests come in, if their code doesn't handle the URL it calls the listeners in the array. However, as far as I can tell this wouldn't work in the second example I've shown above.
Whats the best way to make this work?
What about Connect? Router middleware provides rich Sinatra / Express-like routing.
Example
connect.router(function(app){
app.get('/user/:id', function(req, res, next){
// populates req.params.id
});
app.put('/user/:id', function(req, res, next){
// populates req.params.id
});
})
For advanced use look at http://expressjs.com/guide.html#routing.