Content-LengthとString#lengthとUTF-8

node.jsでレスポンスヘッダにContent-Lengthを指定してレスポンスを返してやろう、と思って以下のようなコードを書きました。

var data = [
  '<!DOCTYPE html>',
  '<meta charset="utf-8">',
  '<title>test</title>',
  '<style>',
  '  p {text-align: center;}',
  '</style>',
  '<p>インターネット</p>'
].join('\n');

res.writeHead(200, {
  'Content-Type': 'text/html; charset=utf-8'
  'Content-Length': data.length
});
res.end(data);

ブラウザでページを見たところ、「インター」で切れてしまう事に。ん?と思って以下を実行してみると

> 'あ'.length
1

ああ……という感じ。文字数でなくてバイト数が欲しいので

 res.writeHead(200, {
   'Content-Type': 'text/html; charset=utf-8'
-  'Content-Length': data.length
+  'Content-Length': Buffer.byteLength(data, 'utf8')
 });
 res.end(data);

と修正したらちゃんと表示されたのでした。


参考:
文字列のバイト数を求める - hokaccha memo