Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
468 views
in Technique[技术] by (71.8m points)

javascript - Node.js / Express.js - How to override/intercept res.render function?

I'm building a Node.js app with Connect/Express.js and I want to intercept the res.render(view, option) function to run some code before forwarding it on to the original render function.

app.get('/someUrl', function(req, res) {

    res.render = function(view, options, callback) {
        view = 'testViews/' + view;
        res.prototype.render(view, options, callback);
    };

    res.render('index', { title: 'Hello world' });
});

It looks like a contrived example, but it does fit in an overall framework I'm building.

My knowledge of OOP and Prototypal inheritance on JavaScript is a bit weak. How would I do something like this?


Update: After some experimentation I came up with the following:

app.get('/someUrl', function(req, res) {

    var response = {};

    response.prototype = res;

    response.render = function(view, opts, fn, parent, sub){
        view = 'testViews/' + view;
        this.prototype.render(view, opts, fn, parent, sub);
    };

    response.render('index', { title: 'Hello world' });
});

It seems to work. Not sure if it's the best solution as I'm creating a new response wrapper object for each request, would that be a problem?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Old question, but found myself asking the same thing. How to intercept res render? Using express 4.0x something now.

You can use/write middleware. The concept was a bit daunting to me at first, but after some reading it made a little more sense. And just for some context for anyone else reading this, the motivation for overriding res.render was to provide global view variables. I want session to be available in all my templates without me having to type it in every res object.

The basic middleware format is.

app.use( function( req, res, next ) {
    //....
    next();
} );

The next param and function call are crucial to execution. next is the callback function, to allow multiple middleware to do their thing without blocking. For a better explanation read here

This can then be used to override render logic

app.use( function( req, res, next ) {
    // grab reference of render
    var _render = res.render;
    // override logic
    res.render = function( view, options, fn ) {
        // do some custom logic
        _.extend( options, {session: true} );
        // continue with original render
        _render.call( this, view, options, fn );
    }
    next();
} );

I've tested this code, using express 3.0.6. It should work with 4.x without issue. You can also override specific URLs combos with

app.use( '/myspcificurl', function( req, res, next ) {...} );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...