當實現在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
});
});
假設輸入是UTF8編碼,使用req.setEncoding('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
});
});
我說得對,還是這已經通過HTTP的請求類照顧?
謝謝你的提問。我以爲我瘋了是這個星球上唯一認爲這可能是個問題的人;-) – dty 2013-07-04 15:01:21