Nodejs 在发请求post时候,中文字符串长度的坑

Nodejs 在发请求post时候,中文字符串长度的坑

自己写一个脚本枉自己写的exprss的服务器发post请求,老是出错,后来发现是Content-Length的问题。

刚开始是这样写的: var headers = { ‘Content-Type’: ‘application/json’, ‘Content-Length’: sentString.length }; 中文的怎么都不行老是报json转换异常,英文就可以。 后来用下面的代码测试才知道原来string长度不等于buf的长度啊。

var str = JSON.stringify({words:'测试1234567890中文'});
console.log(str.length);
console.log(new Buffer(str).length);

打印结果如下:

26
34

自己果然是个小菜鸟!希望新手遇到这个问题的时候注意吧。 贴一下小脚本吧

var index = function()
{
 var str = new Buffer(JSON.stringify({words:'我的测试'}));
var headers = {
  'Content-Type': 'application/json',
  'Content-Length': str.length
};

console.log(str); var options = { host: ‘localhost’, path: ‘/segment’, port: 3000, method: ‘POST’, headers: headers };

var request = http.request(options, function(response) { response.setEncoding(‘utf8’); var buf = []; var size =0; response.on(‘data’, function (chunk) { var buftmp = new Buffer(chunk); buf.push(buftmp); size += buftmp.length; }).on(‘end’, function () { console.log(Buffer.concat(buf,size).toString()); }).on(‘error’, function (error) { console.log(error.message); }).on(‘aborted’, function() { console.log(‘aborted’); }); }); request.write(str); request.end(); }


6 回复

Nodejs 在发请求post时候,中文字符串长度的坑

自己写一个脚本来测试使用express服务器发送post请求时,老是出错,后来发现是Content-Length的问题。

刚开始是这样写的:

var headers = {
  'Content-Type': 'application/json',
  'Content-Length': sentString.length
};

中文的字符串怎么都不行,总是报json转换异常,而英文的字符串却没有问题。

后来用下面的代码测试才知道原来字符串的长度并不等于Buffer的长度:

var str = JSON.stringify({words: '测试1234567890中文'});
console.log(str.length); // 输出:26
console.log(new Buffer(str).length); // 输出:34

打印结果显示,中文字符在JSON字符串中的长度与实际的字节长度不同。这是因为中文字符占用更多的字节。

下面是修改后的示例代码,用于正确地设置Content-Length头,并发送POST请求:

var http = require('http');

var index = function() {
  var str = JSON.stringify({words: '我的测试'});
  var headers = {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(str, 'utf8')
  };

  console.log(str);
  
  var options = {
    host: 'localhost',
    path: '/segment',
    port: 3000,
    method: 'POST',
    headers: headers
  };

  var request = http.request(options, function(response) {
    response.setEncoding('utf8');
    var buf = [];
    var size = 0;
    response.on('data', function (chunk) {
      var buftmp = new Buffer(chunk);
      buf.push(buftmp);
      size += buftmp.length;
    }).on('end', function () {
      console.log(Buffer.concat(buf, size).toString());
    }).on('error', function (error) {
      console.log(error.message);
    }).on('aborted', function() {
      console.log('aborted');
    });
  });

  request.write(str);
  request.end();
}

index();

在这个示例中,我们使用了Buffer.byteLength方法来计算字符串的字节长度,这比直接使用.length属性更准确,特别是在处理包含多字节字符(如中文)的字符串时。这样可以确保Content-Length头被正确设置,从而避免发送POST请求时出现的异常。


buffer没关系。content-length应该是encodeURIComponent之后的字符串长度.

还真是,怎么早没看你的帖子呢

嗯,中文尽量用buffer过一下

您好,DeNA在招聘资深Node.js的职位,您有兴趣了解一下吗?

在发送POST请求时,中文字符串的处理确实是个常见的坑。由于中文字符在Unicode编码中占用多个字节,因此直接使用字符串的长度来设置Content-Length是不准确的。需要将字符串先转换为Buffer对象,然后获取其长度。

下面是改进后的代码示例:

const http = require('http');
const url = require('url');

// 创建服务器
const server = http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/segment') {
    let body = [];
    req.on('data', chunk => {
      body.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(body);
      console.log(`Received: ${body.toString()}`);
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end('Request received\n');
    });
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found\n');
  }
});

server.listen(3000, () => {
  console.log('Server is running on port 3000');
});

// 发送POST请求
const index = () => {
  const data = JSON.stringify({ words: '我的测试' });
  const str = Buffer.from(data);

  const headers = {
    'Content-Type': 'application/json',
    'Content-Length': str.length
  };

  const options = {
    hostname: 'localhost',
    path: '/segment',
    port: 3000,
    method: 'POST',
    headers: headers
  };

  const request = http.request(options, (response) => {
    let responseBody = '';
    response.on('data', (chunk) => {
      responseBody += chunk.toString();
    }).on('end', () => {
      console.log(`Response: ${responseBody}`);
    }).on('error', (error) => {
      console.log(error.message);
    });
  });

  request.write(str);
  request.end();
};

index();

在这个示例中,我们使用Buffer.from将JSON字符串转换成Buffer对象,并根据Buffer对象的长度来设置Content-Length。这样可以确保Content-Length的值正确反映实际发送的数据大小。

回到顶部