问题
I have a middleware that rewrites the request.url. However in the next() middleware, the request.url is still the original unmodified url.
Example:
var express = require('express');
var router = express.Router();
router.use(function(req, res, next) {
console.log('Before Rewrite',req.url);
if(/^\/v[1-9]/.test(req.originalUrl) ) {
console.log('Rewritten');
req.url = '/api' + req.originalUrl;
}
console.log('After Rewrite',req.url);
next();
});
router.use('/api', function(req, res, next) {
console.log('Next', req.url);
next();
});
With an example url of '/v3/foo' the following is output to console:
Before Rewrite /v3/foo
Rewritten
After Rewrite /api/v3/foo
Next /v3/foo
Any thoughts on why the request changes do not persist on to the next middleware?
回答1:
Thanks to the link from @kelz to the Express next() code, I have a better understanding of how Express handles urls. It seems that req.url is writeable because Express removes the root of the url when matching. For example with an original url of '/foo/bar', if you have this:
router.use('/foo', someMiddleWare);
Then req.url within someMiddleWare will now be '/bar' i.e. with the matched root removed. This is why we have req.originalUrl (which is not writeable) to persist the unaltered url.
As my original approach to rewriting the url can't work, I opted for a simpler solution:
router.all(/^\/v[1-9]/, function(req, res) { res.redirect('/api' + req.originalUrl); });
This way, after the redirect, the req.originalUrl is as it should be for my later middleware.
回答2:
You are not sharing the same object in both functions. The moment you change the value of req in the middleware function the scope is bound only inside that function.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Example:
function doAThing(a) {
a = 5;
return;
}
var n = 4;
doAThing(n);
console.log(n); // 4
来源:https://stackoverflow.com/questions/34596780/do-changes-to-request-url-in-express-middleware-persist-on-to-the-next-middlewar