Reputation: 4460
The end points of my API-application render data based on the request mime type. I have implementing express' response.format() to distinguish between the req types.
However, the handler also needs to be able to distinguish the formats based on the file extension like
/route/users.json
Express' response.format doesn't handle that case.
Therefore I was hoping I could simply use a middleware function and set the headers Content-Type according to the extension like this:
app.use('/', (req, res, next) => {
let contentType;
if (req.path.match(/\.json/)) {
contentType = 'application/json';
} else if (req.path.match(/\.xml/)) {
contentType = 'text/xml';
}
if (contentType) {
req.headers['Content-Type'] = contentType;
}
next();
});
But that's not working. I have checked whether the middleware is actually executed and that's the case. However the Content-Type does not persist.
So when the actual request handler is being executed the Content-Type is missing.
What am I doing wrong here?
Upvotes: 3
Views: 3283
Reputation: 4460
So, the non-persistent content content type wasn't the problem. In fact the content-type was there, but due to focussing on the wrong problem, I got quite confused.
Anyway, the real "problem" was, that the header mime type was not available in the request header's accept field.
If that's not set express and any other sane web server won't recognize it.
Here's what I neede to do:
module.exports = function fileExtensionHeader(req, res, next) {
let contentType;
if (req.path.match(/\.json/)) {
contentType = 'application/json';
} else if (req.path.match(/\.xml/)) {
contentType = 'text/xml';
}
if (contentType) {
req.headers['Content-Type'] = contentType;
req.headers.accept = `${contentType},${req.headers.accept}`; // this line did the trick
}
next();
};
A word of warning:
This creates a potential security risk. The mime type should only be set by the request header sent by the browser.
No one should ever allow to set the mime type by file extension without a good reason.
Upvotes: 2