Node.jsの中にHTTPサービスを実装する場合、全体の要求エンティティ(クライアントによってアップロードされたデータ、JSONデータとの例えばPOST)を取得するために使用される以下のようなサンプルコードがたくさんある:リクエスト本体でUTF8文字を解析する際の問題?
var http = require('http');
var server = http.createServer(function(req, res) {
var data = '';
req.setEncoding('utf8');
req.on('data', function(chunk) {
data += chunk;
});
req.on('end', function() {
// parse data
});
});
req.setEncoding('utf8')
を使用すると、入力がUTF8でエンコードされていると仮定して、入力バイトを自動的に文字列にデコードします。しかし、私はそれが壊れると感じる。マルチバイトのUTF8文字の途中で終了するデータのまとまりを受け取ったらどうなりますか?私たちは、これをシミュレートすることができます
> new Buffer("café")
<Buffer 63 61 66 c3 a9>
> new Buffer("café").slice(0,4)
<Buffer 63 61 66 c3>
> new Buffer("café").slice(0,4).toString('utf8')
'caf?'
だから、代わりに適切に最後の文字を解読するために、次のバイトを待つので誤っ文字を取得します。
したがって、リクエストオブジェクトがこれを気にかけない限り、完全にデコードされた文字だけがチャンクにプッシュされることを確かめて、このユビキタスコードサンプルは破損します。
代替は、バッファサイズ制限の問題を扱う、バッファを使用することです:
var http = require('http');
var MAX_REQUEST_BODY_SIZE = 16 * 1024 * 1024;
var server = http.createServer(function(req, res) {
// A better way to do this could be to start with a small buffer
// and grow it geometrically until the limit is reached.
var requestBody = new Buffer(MAX_REQUEST_BODY_SIZE);
var requestBodyLength = 0;
req.on('data', function(chunk) {
if(requestBodyLength + chunk.length >= MAX_REQUEST_BODY_SIZE) {
res.statusCode = 413; // Request Entity Too Large
return;
}
chunk.copy(requestBody, requestBodyLength, 0, chunk.length);
requestBodyLength += chunk.length;
});
req.on('end', function() {
if(res.statusCode == 413) {
// handle 413 error
return;
}
requestBody = requestBody.toString('utf8', 0, requestBodyLength);
// process requestBody as string
});
});
は、右Iアム、またはこれはすでにhttpリクエストクラスで世話をしていますか?
ありがとうございます。私は惑星上で唯一の人であると怒っていると思っていましたが、これは問題だと思っていました;-) – dty