使用Node.JS提供HTTP/1.0响应(未知内容长度,分块传输编码)

Bra*_*rad 13 http http-1.0 http-1.1 transfer-encoding node.js

问题

我通过Node.JS提供未知长度的资源.因此,Content-Length无法设置标头.对于HTTP 1.1,需要将chunked编码用于此类资源.Node.JS知道这一点并使用chunked transfer encoding自己发送我的数据,具有以下标头:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: close
...
Run Code Online (Sandbox Code Playgroud)

对于行为良好的客户来说,这一切都很好. 但是,我必须支持一些表现不佳的客户端(即Android 2.2及更早版本). 这些客户端不支持正确的分块传输编码.

修复尝试#1

我最初的想法是将编码设置为none如此:

response.writeHead(200, {'Transfer-Encoding': 'none'});
Run Code Online (Sandbox Code Playgroud)

这会禁用Node.JS的自动分块编码,并保持与大多数客户端的兼容性.然而,现在我已经破坏了Android 2.3+客户端,因为当他们看到这样一个虚假的传输编码头时,他们只是咳嗽和窒息.

修复尝试#2(我需要帮助的地方)

当我发出请求时HTTP/1.0,服务器正确地返回没有分块编码的响应:

HTTP/1.1 200 OK
Connection: close
...
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题,并允许我提供适用于我所有麻烦客户的流.我不必发送伪造的标题Transfer-Encoding,我仍然不必指定内容的长度.

如何强制Node.JS的HTTP服务器始终以HTTP/1.0模式提供服务?

Bra*_*rad 8

出于我的目的,我发现了一种使用响应对象的未记录属性来禁用强制使用chunked的简单方法:

response.useChunkedEncodingByDefault = false;
Run Code Online (Sandbox Code Playgroud)

就这么简单.当然,依赖此属性可用于未来版本的Node.js并不是最好的.也许有更好的解决方案,但这对我来说现在很有用.


Luc*_*iva 2

强制非分块响应,这是正确的方式

有一种受支持的关闭分块编码的方法:您只需Transfer-Encoding使用request.removeHeader(name)删除标头:

response.removeHeader('transfer-encoding');
Run Code Online (Sandbox Code Playgroud)

无论如何,Node.js 都会尊重。甚至还有一个测试可以防止有人意外更改此行为,所以我认为使用它非常安全。

因此,您可以坚持尝试#1,但按照上面的描述进行操作。