如何在输出之前禁用res.writeHead()输出额外的数字?

时间:2017-06-30 12:00:51

标签: node.js express

我用express创建一个http服务器。 以下是服务器代码:

router.get('/', function(req, res, next) {
  // req.socket.setTimeout(Infinity);
  res.writeHead(200, {
    'Content-Type': 'text/plain; charset=utf-8',  // <- Important headers
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  });
  res.write('hell');
  res.write('world');
  res.end();

  // res.write('\n\n');
  // response = res;
});

当我使用netcat来获取网址时。 输出就像这样

GET /sse HTTP/1.1

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/plain; charset=utf-8
Cache-Control: no-cache
Expires: 0
Connection: keep-alive
Keep-Alive: timeout=5, max=97
Date: Fri, 30 Jun 2017 11:50:00 GMT
Transfer-Encoding: chunked

4
hell
5
world
0

我的问题是为什么每个res.write()之前总有一个数字?然后数字似乎是res.write输出的长度。

如何删除号码?

1 个答案:

答案 0 :(得分:3)

这是分块编码的工作原理。您不必预先声明要发送多少字节,而是每个块前面加上它具有的字节数。例如:4表示"hell",5表示"world",最后0表示“不再发送字节”。

您可以看到存在分块编码头:

Transfer-Encoding: chunked

现在,要直接回答您的问题,要删除您必须关闭分块编码的数字。为此,您必须将Content-length标头设置为您将在响应正文中发送的字节数。

例如:

app.get('/', function(req, res, next) {
  res.writeHead(200, {
    'Content-Type': 'text/plain; charset=utf-8',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-length': 9, // <<<--- NOTE HERE
  });
  res.write('hell');
  res.write('world');
  res.end();
});

(当然在实际代码中你必须要么计算响应的长度,要么建立一个字符串或缓冲区,并在设置Content-length标题之前得到它的长度。)

但请注意,如果您使用curl或任何其他HTTP客户端,那么它将为您“删除”这些数字。只是用netcat你意外地看到了分块编码的底层实现细节,但所有真正的HTTP客户端都可以正常处理。

通常在HTTP中,你在头文件中声明整个响应的长度,然后发送正文 - 一个部分,多个块,无论如何 - 但它必须与你声明的长度相同。这意味着在知道要发送的所有内容的长度之前,无法开始发送数据。使用分块编码,它足以声明您发送的每个块的长度,但您不必知道整个响应的长度 - 这甚至可能是无限的,这取决于您。它允许您在发送任何内容后立即开始发送,这非常有用。