Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@satosystems

Express.js で charset を UTF-8 以外にする方法

More than 1 year has passed since last update.

Express.js はデフォルトの charset として UTF-8 が設定されます。
ほとんどのケースではこの振る舞いで問題はないのですが、クライアント側が UTF-8 を認識/取り扱いできないようなケース(IoT クライアントなど)で問題が発生します。

Express.js でレスポンスを返す場合、以下のようにすると思います。

router.get('/foo/var/baz', (req, res) => {
  res.status(200)
  res.set('Content-Type: text/csv; charset=us-ascii')
  res.send('key,value\r\nhoge,fuga\r\npiyo,puyo')
})

このサーバに対して curl でリクエストを送ると、以下のようになります。

$ curl -i localhost:3000/foo/bar/baz
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/csv; charset=utf-8
Content-Length: 31
ETag: W/"1f-l8FL4++qBiqYIj/prv0x2jtd7e8"
Date: Fri, 09 Aug 2019 03:05:26 GMT
Connection: keep-alive

key,value
hoge,fuga
piyo,puyo

Content-Type が勝手に UTF-8 に書き換わっています。

これは Charset UTF-8 appended to Content-Type when using res.json · Issue #2921 · expressjs/express によるとどうやら仕様のようで、要約すると:

If you leave it up to us to choose UTF-8, we're going to modify your Content-Type header, that's just how it is.

UTF-8 を選択するのであれば、私達の方でで Content-Type ヘッダを変更するのでお任せください。
```

ということです。

任意の charset を指定したい場合は、以下のように行います。

Buffer を使用する

router.get('/foo/var/baz', (req, res) => {
  res.status(200)
  res.set('Content-Type: text/csv; charset=us-ascii')
  res.set('Content-Type', 'text/csv; charset=us-ascii')
  res.send(Buffer.from('key,value\r\nhoge,fuga\r\npiyo,puyo'))
})
$ curl -i localhost:3000/foo/bar/baz
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/csv; charset=us-ascii
Content-Length: 31
ETag: W/"1f-l8FL4++qBiqYIj/prv0x2jtd7e8"
Date: Fri, 09 Aug 2019 03:09:53 GMT
Connection: keep-alive

key,value
hoge,fuga
piyo,puyo

これが最も簡単な対応方法だと思います。

write/end を使用する

router.get('/foo/var/baz', (req, res) => {
  res.status(200)
  res.set('Content-Type: text/csv; charset=us-ascii')
  res.write('key,value\r\nhoge,fuga\r\npiyo,puyo')
  res.end()
})
$ curl -i localhost:3000/foo/bar/baz
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/csv; charset=us-ascii
Date: Fri, 09 Aug 2019 03:06:47 GMT
Connection: keep-alive
Transfer-Encoding: chunked

key,value
hoge,fuga
piyo,puyo

この方法は Buffer を使用する方法と異なり新たにオブジェクトを生成しないのですが、Transfer-Encoding が chunked になり、Content-Length ヘッダがなくなってしまいます。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
systemi
ランドマークタワーを拠点に活躍する独立系システム会社

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?