node.js – 在请求体中解析UTF8字符的问题?

前端之家收集整理的这篇文章主要介绍了node.js – 在请求体中解析UTF8字符的问题?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在node.js中实现HTTP服务时,有很多示例代码如下所示用于获取整个请求实体(客户端上传的数据,例如带有 JSON数据的POST):
  1. var http = require('http');
  2.  
  3. var server = http.createServer(function(req,res) {
  4. var data = '';
  5. req.setEncoding('utf8');
  6.  
  7. req.on('data',function(chunk) {
  8. data += chunk;
  9. });
  10.  
  11. req.on('end',function() {
  12. // parse data
  13. });
  14. });

假设输入是UTF8编码的,使用req.setEncoding(‘utf8’)会自动将输入字节解码为字符串.但我觉得它可以打破.如果我们收到一个以多字节UTF8字符结尾的数据块怎么办?我们可以模拟这个:

  1. > new Buffer("café")
  2. <Buffer 63 61 66 c3 a9>
  3. > new Buffer("café").slice(0,4)
  4. <Buffer 63 61 66 c3>
  5. > new Buffer("café").slice(0,4).toString('utf8')
  6. 'caf?'

所以我们得到一个错误的字符,而不是等待下一个字节正确解码最后一个字符.

因此,除非请求对象处理这个问题,确保只将完全解码的字符推入块中,否则这个无处不在的代码示例将被破坏.

另一种方法是使用缓冲区,处理缓冲区大小限制的问题:

  1. var http = require('http');
  2. var MAX_REQUEST_BODY_SIZE = 16 * 1024 * 1024;
  3.  
  4. var server = http.createServer(function(req,res) {
  5. // A better way to do this could be to start with a small buffer
  6. // and grow it geometrically until the limit is reached.
  7. var requestBody = new Buffer(MAX_REQUEST_BODY_SIZE);
  8. var requestBodyLength = 0;
  9.  
  10. req.on('data',function(chunk) {
  11. if(requestBodyLength + chunk.length >= MAX_REQUEST_BODY_SIZE) {
  12. res.statusCode = 413; // Request Entity Too Large
  13. return;
  14. }
  15. chunk.copy(requestBody,requestBodyLength,chunk.length);
  16. requestBodyLength += chunk.length;
  17. });
  18.  
  19. req.on('end',function() {
  20. if(res.statusCode == 413) {
  21. // handle 413 error
  22. return;
  23. }
  24.  
  25. requestBody = requestBody.toString('utf8',requestBodyLength);
  26. // process requestBody as string
  27. });
  28. });

我是对的,还是已经由http请求类处理了?

解决方法

这是自动处理.节点中有一个string_decoder模块,当您调用setEncoding时会加载该模块.解码器将检查收到的最后几个字节,如果它们不是完整字符,则将它们存储在’data’的发送之间,因此数据将始终获得正确的字符串.如果你不做setEncoding,并且不自己使用string_decoder,那么发出的缓冲区可能会出现你提到的问题.

文档虽然没有多大帮助,http://nodejs.org/docs/latest/api/string_decoder.html,但你可以在这里看到模块,https://github.com/joyent/node/blob/master/lib/string_decoder.js

“setEncoding”的实现和发射逻辑也使它更加清晰.

> setEncoding:https://github.com/joyent/node/blob/master/lib/http.js#L270
> _emitData https://github.com/joyent/node/blob/master/lib/http.js#L306

猜你在找的Node.js相关文章