I need to modify the response data a module sends to the client, as the module uses res.send i can't seem to figure out a way for me to modify the data before it's carried out to the client.
Is there any kind of middleware/event that I can use to catch the res.send and modify the data before its executed?
I am aware that router.use exists but it's called before the router.post function and not before the res.send is sent to the client. So I need some kind of middleware which is called after the router.post function is done but before anything is sent to the client.
Well you can override the send function:
app.use(function (req, res) {
var send = res.send;
res.send = function (body) { // It might be a little tricky here, because send supports a variety of arguments, and you have to make sure you support all of them!
// Do something with the body...
send.call(this, body);
};
});
If you want to support more than just calling send(like calling end method), then you have to override more functions...
You can check connect-livereload on how it adds a script to any html output.
One more solution from here:
expressApp.use(function (req, res, next) {
req.on("end", function () {
console.log('on request end');
});
next();
});
Important Note: To work, this needs to be placed before body parser since it recreates the response object. see this answer
It can be done by overriding res.send
We override the res.send function to capture the response body in our API analytics tool as follows
// It will monkey patch the res.send.
// The patch intercepts the send invocation, executes is logic such as atatus.setResponseBody
// then restores the original send function and invokes that to finalize the req/res chain
const resSendInterceptor = (res, send) => (content) => {
// Set response body in Atatus Analytics
// Atatus is our API analytics tool
atatus.setResponseBody(content || '');
// TODO: You can modify your response body as you wish.
// Invoke the original send function.
res.send = send;
send.apply(this, arguments);
};
// Express Middleware
app.use((req, res, next) => {
// Overrides res.send
res.send = resSendInterceptor(res, res.send);
return next();
});
Your lack of code makes it really hard to answer your question, but you could use something like
Express 4.0:
router.use('/path', function (req, res) {
// Modify req
});
.use on a route will parse that before continuing on to the actual route so if somebody submitted a form or something, it will hit the .use before it goes to the .post or .get
Or you can do
Express 4.0:
app.use(function (req, res) {
// Modify Req
if (req.body.hasOwnProperty('some_form_name')) {
// Do Somthing
}
});
Which is the same thing, but it will be called before every request for every route.
Not sure if this answers your question but I think this might be what you're looking for?
Related
I have two endpoints in a node js app:
app.get('search', myGetController);
app.post('add', myPostController);
For simplicity, let's assume both services have only the following code:
exports.myGetController = function(req, res) {
res.status(404).json({ error: "not found" });
};
I want to have a middleware that is executed after the processing of the controllers, but before they are sent to the browser, so I can add a header based on the body of the response.
// process all responses to add ed25519
app.use(function(req, res, next) {
res.setHeader('CharCount', [How To get Body content]);
next();
});
I have two questions:
First of all, I would like to have all my controllers pass by that middleware after processing.
Second, I would like to access the body content so I can generate a header based on its content.
UPDATE
I have tried the suggested answer someone posted, and it is not working, or I am missing something.
This is what I have (before setting up my routes):
app.use(function(req, res, next) {
const oldResJson = res.json;
res.json = function(body) {
res.setHeader('myToken', generateHeaderBasedOnBody(oldResJson));
oldResJson.call(res, body);
}
next();
});
The response that is being passed to my method is an empty string, even though the response sent by the service is not empty. Am I doing this in the wrong place, or what am I missing?
One solution for this issue would be to override the res.json function like so:
// process all responses to add ed25519
app.use(function(req, res, next) {
const oldResJson = res.json;
res.json = function(body) {
res.setHeader('CharCount', /* Use body here */);
oldResJson.call(res, body);
}
next();
});
By doing this, you don't even need to change your controllers.
In Express middleware, it should be taking 3 parameters: request, response, next.
However, in the 2nd middleware in the code where I copied from a book, but only use request, response. What is the reason here? and is next optional?
var express = require("express");
var http = require("http");
var app = express();
app.use(function(request, response, next) {
console.log("In comes a " + request.method + " to " + request.url);
next();
});
app.use(function(request, response) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Hello, world!");
});
http.createServer(app).listen(3000);
next() is called when you want the routing for this request to continue onto the next middleware or the next route handler for this request. It is common to have more than one middleware that might examine a given request so if you did not send a response and want normal routing to continue for this request, then you would call next() when you were done with your processing and you want routing to continue.
If you have already sent a response and thus do not want routing to continue, then you do not call next().
It is up to you whether you declare the parameter next or not. If you never intend to call it, then you don't need to declare it as a parameter (it is still passed, but you don't have to declare it if you're not going to use it).
So, you can declare your middleware/requeset handler with parameters req and res like this:
app.use("/someRoute", function(req, res) {
res.send("hello");
});
Or, with parameters req, res and next like this:
app.use("/someRoute", function(req, res, next) {
if (req.query.x) {
// don't handle this request here, let some other route
// handler following this handle it
next();
} else {
// send the response, no more route handlers after this
res.send("hello");
}
});
It makes no difference to Express whether you declare the next argument or not. If you plan on using it, then declare it. If you don't plan on using it, then there is no reason to declare it, but it is passed anyway. This is true of all Javascript function arguments. If you don't declare all the arguments as named arguments, it just makes it harder to access them, but they are still there (for completeness, then can still be accessed through the arguments object).
There's also a special case route handler with four arguments (err, req, res, next) which is used for error handling (when next(err) is called), but that's not what your question is about. Express does treat route handlers with four arguments declared differently. It registers them as error handlers.
With express.js there are 4 types of basic handlers.
2 - req, res
3 - req, res, next
4 - err, req, res, next
If you have 2 arguments, express will always assign a req and res to them, no matter what you call them. It's just a calling convention that is widely used by the express community that makes for cleaner, readable and understandable code.
In Node.js Express - using app.use functions-
why don't I have to do this:
app.use(function(req,res,next){
//do something here
next(req,res);
});
usually I just do this and it works
app.use(function(req,res,next){
//do something here
next();
});
?
next() already knows the req and res for the currently executing request, thus you just call it directly. It is a unique function created just for this request. It also keeps track of where you currently are in the middleware stack such that calling next() executes the next middleware in the chain.
If you look at the express source code for the router, you can actually see the locally defined next() function and can see how it has access to a bunch of closure-defined variables that include req, res and index counter that it uses for advancing through the middleware stack and a bunch of other variables. Thus, it already has access to everything it needs to launch the next middleware call so there is no reason to pass it those things.
FYI, one of the great things about using open source is that you can always just go look at the code yourself and see what it does.
When invoking next(), you have several choices:
You can invoke it as next() and this will just invoke the next middleware handler in the stack.
You can invoke it as next('route') and it will skip to the next route handler.
You can pass an error next(err) and stop all further middleware or router handling except for error handlers.
The details are documented here: http://expressjs.com/guide/error-handling.html.
Here's a note from that page:
next() and next(err) are analogous to Promise.resolve() and
Promise.reject(). They allow you to signal to Express that this
current handler is complete and in what state. next(err) will skip all
remaining handlers in the chain except for those that are set up to
handle errors as described in the next section.
The use of next accepts an optional Error object. if you pass nothing to it, it assumes you're ready to continue onto the next piece of middleware or your actual mounted handler. Otherwise, if you pass an instance of an Error object, you'll bypass your mounted handler (and sequential middleware) and go directly to the error handler.
app.use(function (req, res, next) {
if (!req.user || !req.user.isAuthorized) next(Error('not allowed'))
else next()
})
app.get('/:user', function (req, res, next) {
res.render('users/index', { user: req.user })
})
app.use(function (err, req, res, next) {
console.log(err.message) // not allowed
res.render('500', err)
})
I tried to understand the internal working by looking in the sources provided by jfriend00, but didn't wanted to loose too much time trying to isolate the specific part which handles the callbacks.
So I tried my own:
jsfiddle
function MW(req, res){
var req1 = req, res1 = res;
Array.prototype.shift.apply(arguments);
Array.prototype.shift.apply(arguments);
var MWs = arguments;
console.log(MWs, req1, res1);
function handle(index){
if(index ===MWs.length-1){
return ()=>{MWs[index](req1, res1, ()=>{})};
}
return ()=>{MWs[index](req1, res1, handle(index+1))};
}
var next = handle(0);
next();
}
Basically, it uses recursion to build the chain of callbacks.
You can then use it as Express use/get/post/put/...:
MW(req, res,
(req, res, next)=>{
console.log("first");
req.locals = {
token : 'ok'
};
res.canSend =false;
next();
},
(req, res, next)=>{
console.log("second");
console.log(req.locals.token, res.canSend);
next();
}
);
I would like to have a middleware function which modifies the response body.
This is for an express server.
Something like:
function modify(req, res, next){
res.on('send', function(){
res.body = res.body + "modified"
});
next();
}
express.use(modify);
I don't understand what event to listen for. Any help or documentation would be appreciate.
You don't need to listen to any events. Just make it
function modify(req, res, next){
res.body = res.body + "modified";
next();
}
And use it after you use the router. This way after all your routes have executed you can modify the body
I believe the OP actually wants to modify the response stream once a middleware has handled the request. Look at the bundled Compress middleware implementation for an example of how this is done. Connect monkey patches the ServerResponse prototype to emit the header event when writeHead is called, but before it is completed.
express-mung is designed for this. Instead of events its just more middleware. Your example would look something like
const mung = require('express-mung')
module.exports = mung.json(body => body.modifiedBy = 'me');
Overwriting the response's write method seemed to work for me with Express 4. This allows modifying the response's body even when it's a stream.
app.use(function (req, res, next) {
var write = res.write;
res.write = function (chunk) {
if (~res.getHeader('Content-Type').indexOf('text/html')) {
chunk instanceof Buffer && (chunk = chunk.toString());
chunk = chunk.replace(/(<\/body>)/, "<script>alert('hi')</script>\n\n$1");
res.setHeader('Content-Length', chunk.length);
}
write.apply(this, arguments);
};
next();
});
Just make sure to register this middleware before any other middleware that may be modifying the response.
There seems to be a module for doing just this called connect-static-transform, check it out:
https://github.com/KenPowers/connect-static-transform
A connect middleware which allows transformation of static files before serving them.
And it comes with examples, like this one.
Almost every Express app I see has an app.use statement for middleware but I haven't found a clear, concise explanation of what middleware actually is and what the app.use statement is doing. Even the express docs themselves are a bit vague on this. Can you explain these concepts for me please?
middleware
I'm halfway through separating the concept of middleware in a new project.
Middleware allows you to define a stack of actions that you should flow through. Express servers themselves are a stack of middlewares.
// express
var app = express();
// middleware
var stack = middleware();
Then you can add layers to the middleware stack by calling .use
// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
next();
});
A layer in the middleware stack is a function, which takes n parameters (2 for express, req & res) and a next function.
Middleware expects the layer to do some computation, augment the parameters and then call next.
A stack doesn't do anything unless you handle it. Express will handle the stack every time an incoming HTTP request is caught on the server. With middleware you handle the stack manually.
// express, you need to do nothing
// middleware
stack.handle(someData);
A more complete example :
var middleware = require("../src/middleware.js");
var stack = middleware(function(data, next) {
data.foo = data.data*2;
next();
}, function(data, next) {
setTimeout(function() {
data.async = true;
next();
}, 100)
}, function(data) {
console.log(data);
});
stack.handle({
"data": 42
})
In express terms you just define a stack of operations you want express to handle for every incoming HTTP request.
In terms of express (rather than connect) you have global middleware and route specific middleware. This means you can attach a middleware stack to every incoming HTTP requests or only attach it to HTTP requests that interact with a certain route.
Advanced examples of express & middleware :
// middleware
var stack = middleware(function(req, res, next) {
users.getAll(function(err, users) {
if (err) next(err);
req.users = users;
next();
});
}, function(req, res, next) {
posts.getAll(function(err, posts) {
if (err) next(err);
req.posts = posts;
next();
})
}, function(req, res, next) {
req.posts.forEach(function(post) {
post.user = req.users[post.userId];
});
res.render("blog/posts", {
"posts": req.posts
});
});
var app = express.createServer();
app.get("/posts", function(req, res) {
stack.handle(req, res);
});
// express
var app = express.createServer();
app.get("/posts", [
function(req, res, next) {
users.getAll(function(err, users) {
if (err) next(err);
req.users = users;
next();
});
}, function(req, res, next) {
posts.getAll(function(err, posts) {
if (err) next(err);
req.posts = posts;
next();
})
}, function(req, res, next) {
req.posts.forEach(function(post) {
post.user = req.users[post.userId];
});
res.render("blog/posts", {
"posts": req.posts
});
}
], function(req, res) {
stack.handle(req, res);
});
After simplifying things, a web server can be seen as a function that takes in a request and outputs a response. So if you view a web server as a function, you could organize it into several pieces and separate them into smaller functions so that the composition of them will be the original function.
Middlewares are the smaller functions that you can compose with others and the obvious benefit is that you can reuse them.
I add a late answer to add something not mentioned in the previous answers.
By now it should be clear that middleware is/are function(s) run between the client request and the server answer. The most common middleware functionality needed are error managing, database interaction, getting info from static files or other resources. To move on the middleware stack the next callback must be called, you can see it in the end of middleware function to move to the next step in the flow.
You can use the app.use approach and have a flow like this:
var express = require('express'),
app = express.createServer(),
port = 1337;
function middleHandler(req, res, next) {
console.log("execute middle ware");
next();
}
app.use(function (req, res, next) {
console.log("first middle ware");
next();
});
app.use(function (req, res, next) {
console.log("second middle ware");
next();
});
app.get('/', middleHandler, function (req, res) {
console.log("end middleware function");
res.send("page render finished");
});
app.listen(port);
console.log('start server');
but you can also use another approach and pass each middleware as function arguments. Here is a example from the MooTools Nodejs website where midleware gets the Twitter, Github and Blog flow before the response is sent back to the client. Note how the functions are passed as arguments in app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){. Using app.get will only be called for GET requests, app.use will be called for all requests.
// github, twitter & blog feeds
var githubEvents = require('./middleware/githubEvents')({
org: 'mootools'
});
var twitter = require('./middleware/twitter')();
var blogData = require('./blog/data');
function getLatestBlog(req, res, next){
blogData.get(function(err, blog) {
if (err) next(err);
res.locals.lastBlogPost = blog.posts[0];
next();
});
}
// home
app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
res.render('index', {
title: 'MooTools',
site: 'mootools',
lastBlogPost: res.locals.lastBlogPost,
tweetFeed: res.locals.twitter
});
});
expressjs guide has pretty neat answer to your question, I highly recommend you to read that, I am posting a short snippet of the guide, the guide is quite good.
Writing middleware for use in Express apps
Overview
Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
Middleware functions can perform the following tasks:
Execute any code.
Make changes to the request and the response objects.
End the request-response cycle.
Call the next middleware in the stack.
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.
Example
Here is an example of a simple “Hello World” Express application. The remainder of this article will define and add two middleware functions to the application: one called myLogger that prints a simple log message and another called requestTime1 that displays the timestamp of the HTTP request.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
Middleware function myLogger
Here is a simple example of a middleware function called “myLogger”. This function just prints “LOGGED” when a request to the app passes through it. The middleware function is assigned to a variable named myLogger.
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
Notice the call above to next(). Calling this function invokes the next middleware function in the app. The next() function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The next() function could be named anything, but by convention it is always named “next”. To avoid confusion, always use this convention.
To load the middleware function, call app.use(), specifying the middleware function. For example, the following code loads the myLogger middleware function before the route to the root path (/).
var express = require('express')
var app = express()
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
app.use(myLogger)
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
Every time the app receives a request, it prints the message “LOGGED” to the terminal.
The order of middleware loading is important: middleware functions that are loaded first are also executed first.
If myLogger is loaded after the route to the root path, the request never reaches it and the app doesn’t print “LOGGED”, because the route handler of the root path terminates the request-response cycle.
The middleware function myLogger simply prints a message, then passes on the request to the next middleware function in the stack by calling the next() function.
This post will only contain myLogger middleware, for further post you could go to the original expressjs guide here.
=====Very very simple explanation=====
Middlewares are often used in the context of Express.js framework and are a fundamental concept for node.js . In a nutshell, Its basically a function that has access to the request and response objects of your application. The way I'd like to think about it, is a series of 'checks/pre-screens' that the request goes through before the it is handled by the application. For e.g, Middlewares would be a good fit to determine if the request is authenticated before it proceeds to the application and return the login page if the request is not authenticated or for logging each request. A lot of third-party middlewares are available that enables a variety of functionality.
Simple Middleware example:
var app = express();
app.use(function(req,res,next)){
console.log("Request URL - "req.url);
next();
}
The above code would be executed for each request that comes in and would log the request url, the next() method essentially allows the program to continue. If the next() function is not invoked, the program would not proceed further and would halt at the execution of the middleware.
A couple of Middleware Gotchas:
The order of middlewares in your application matters, as the request would go through each one in a sequential order.
Forgetting to call the next() method in your middleware function can halt the processing of your request.
Any change the req and res objects in the middleware function, would make the change available to other parts of the application that uses req and res
Middlewares are functions executed in the middle after the input/source then produces an output which could be the final output or could be used by the next middleware until the cycle is complete.
It is like a product that goes through an assembly line where it gets modified as it moves along until it gets completed, evaluated or gets rejected.
A middleware expects some value to work on (i.e. parameter values) and based on some logic the middleware will call or not call the next middleware or send a response back to the client.
If you can't still grasp the middleware concept, it is in a way similar to the Decorator or Chain of command patterns.
Middleware is a subset of chained functions called by the Express js routing layer before the user-defined handler is invoked. Middleware functions have full access to the request and response objects and can modify either of them.
The middleware chain is always called in the exact order in which it has been defined, so it is vital for you to know exactly what a specific piece of middleware is doing. Once a middleware function finishes, it calls the next function in the chain by invoking its next argument as function. After the complete chain gets executed,the user request handler is called.
Keep things simple, man!
Note: the answer is related to the ExpressJS builtin middlware cases, however there are different definitions and use cases of middlewares.
From my point of view, middleware acts as utility or helper functions but its activation and use is fully optional by using the app.use('path', /* define or use builtin middleware */) which don't wants from us to write some code for doing very common tasks which are needed for each HTTP request of our client like processing cookies, CSRF tokens and ..., which are very common in most applications so middleware can help us do these all for each HTTP request of our client in some stack, sequence or order of operations then provide the result of the process as a single unit of client request.
Example:
Accepting clients requests and providing back responses to them according to their requests is the nature of web server technology.
Imagine if we are providing a response with just "Hello, world!" text for a GET HTTP request to our webserver's root URI is very simple scenario and don't needs anything else, but instead if we are checking the currently logged-in user and then responding with "Hello, Username!" needs something more than usual in this case we need a middleware to process all the client request metadata and provide us the identification info grabbed from the client request then according to that info we can uniquely identify our current user and it is possible to response to him/her with some related data.
Hope it to help someone!
In very basic term if i want to explain it like this i learn this from traversymedia youtube channel express crash course.
ok so middle ware is a function who execute after you make a call to your route like this.
var logger = function(req, res, next){
console.log('logging...');
next();
}
app.use(logger);
This logger function execute every time you refresh your page that means you can write anything in it that you required to do after your page get rendered any operation api call, reset things basically anything. and put this middleware before your route function order of middleware is really important or it dons't work