Przy wdrażaniu usług HTTP w node.js, istnieje wiele przykładowy kod jak poniżej używany do dostać całą jednostkę życzenie (dane przesłane przez klienta, na przykład stanowisko z danymi JSON):Problemy z parsowaniem znaków UTF8 w treści żądania?
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
});
});
Korzystanie z req.setEncoding('utf8')
powoduje automatyczne dekodowanie bajtów wejściowych na łańcuch, przy założeniu, że dane wejściowe są zakodowane w UTF8. Ale mam wrażenie, że może się zepsuć. Co stanie się, jeśli otrzymamy fragment danych kończący się w środku wielobajtowej postaci UTF8? Możemy symulować to:
> 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?'
Więc otrzymujemy błędne charakter zamiast czekać na kolejne bajty poprawnie zdekodować ostatni znak.
Dlatego, o ile obiekt żądania nie dba o to, upewniając się, że tylko całkowicie zdekodowane znaki są wciskane w porcje, ta wszechobecna próbka kodu jest zepsuta.
Alternatywą byłoby użycie buforów, obchodzenia się z problemem limitów rozmiar bufora:
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
});
});
mam rację, czy też jest to już załatwione przez klasę żądanie HTTP?
Dziękuję za pytanie. Myślałem, że oszalałem jako jedyna osoba na świecie, która myślała, że to może być problem ;-) – dty