Reputation: 43
I have built an API with Node and Express which returns some JSON. The JSON data is to be read by a web application. Sadly this application only accepts ISO-8859-1 encoded JSON which has proven to be a bit difficult.
I can't manage to return the JSON with the right encoding even though I've tried the methods in the Express documentation and also all tips from googling the issue.
The Express documentation says to use "res.set()" or "res.type()" but none of these is working for me. The commented lines are all the variants that I've tried (using Mongoose):
MyModel.find()
.sort([['name', 'ascending']])
.exec((err, result) => {
if (err) { return next(err) }
// res.set('Content-Type', 'application/json; charset=iso-8859-1')
// res.set('Content-Type', 'application/json; charset=ansi')
// res.set('Content-Type', 'application/json; charset=windows-1252')
// res.type('application/json; charset=iso-8859-1')
// res.type('application/json; charset=ansi')
// res.type('application/json; charset=windows-1252')
// res.send(result)
res.json(result)
})
None of these have any effect on the response, it always turns into "Content-Type: application/json; charset=utf-8".
Since JSON should(?) be encoded in utf-8, is it event possible to use any other encoding with Express?
Upvotes: 3
Views: 2985
Reputation: 5808
If you look at the lib/response.js
file in the Express source code (in your node_modules
folder or at https://github.com/expressjs/express/blob/master/lib/response.js) you'll see that res.json
takes your result
, generates the corresponding JSON representation in a JavaScript String
, and then passes that string to res.send
.
The cause of your problem is that when res.send
(in that same source file) is given a String
argument, it encodes the string as UTF8 and also forces the charset
of the response to utf-8
.
You can get around this by not using res.json
. Instead build the encoded response yourself. First use your existing code to set up the Content-Type header:
res.set('Content-Type', 'application/json; charset=iso-8859-1')
After that, manually generate the JSON string:
jsonString = JSON.stringify(result);
then encode that string as ISO-8859-1 into a Buffer
:
jsonBuffer = Buffer.from(jsonString, 'latin1');
Finally, pass that buffer to res.send
:
res.send(jsonBuffer)
Because res.send
is no longer being called with a String
argument, it should skip the step where it forces charset=utf-8
and should send the response with the charset
value that you specified.
Upvotes: 3