我使用 nginx 1.2.3 来代理脚本:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
脚本同时发送Transfer-encoding: chunked
和Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
我两者都需要,但 nginx 会自动删除Content-Length
:
HTTP/1.1 302 Found
Server: nginx/1.2.3
Content-Type: application/json; charset=utf-8
Content-Length: 58
Connection: keep-alive
Location: /...
因此,客户端不会等待数据块被发送。这曾经与较早版本的 nginx 一起使用。
不幸的是,我无法对 cnst 的帖子发表评论 - 所以我将在这里回答。
该
nginx_http_proxy
模块默认与 HTTP/1.0 中的上游通信。这可以用指令改变proxy_http_version 1.1
。这也可能是您的脚本返回 HTTP/1.0 答案的原因,尽管
307
此版本中不存在分块编码和状态代码。您也不应该将分块编码与重定向一起使用,因为这实际上没有意义。
此外,nginx 似乎并没有将上游的块一个一个地传递给客户端,而是缓冲了上游的响应。标题
Content-Length
字段被忽略,因为它违反了定义。我不得不查看模块的源代码,因为所有这些似乎都没有记录。您可能想尝试
nginx_tcp_proxy_module
将分块内容代理为原始 TCP 数据:Github 上的模块更新(10.04.14)
该
nginx_http_proxy
模块支持X-Accel-*
headers,其中一个 (X-Accel-Buffering: yes|no
) 控制响应是否应该被缓冲。将此标头 (
X-Accel-Buffering: no
) 添加到后端的响应将导致 nginx 直接将块传递给客户端。此标头允许在每个请求的基础上控制缓冲。
该模块还有一个配置指令
proxy_buffering
来启用或禁用响应缓冲(不缓冲意味着发送块将起作用)。此处记录了代理缓冲(基于标头和指令)。
正如 Lukas 暗示的那样,HTTP 1.1 禁止
Content-Length
如果有一个Transfer-Encoding
集合。引用http://www.ietf.org/rfc/rfc2616.txt:
您没有具体说明为什么您的脚本首先需要分块编码,尤其是对于重定向响应。
我在这里看到了很多问题。
Transfer-Encoding: chunked
是一项HTTP/1.1
功能(您的脚本似乎在回复HTTP/1.0
标题)没有
307
_HTTP/1.0
的全部目的
chunked
是你不知道你Content-Length
本来会是什么,所以,chunked
用它来代替提供长度Content-Length
,而长度是在响应正文中提供的,与实际内容混合在一起;脚本预先生成两个标头是没有意义的我个人并不熟悉
chunked
,但根据http://en.wikipedia.org/wiki/Chunked_transfer_encoding和https://www.rfc-editor.org/rfc/rfc2616#section-3.6 上的基本信息。 1,我猜测您的脚本对分块编码的整个处理可能是完全错误的。如果以上内容仍然没有涵盖它,并且实际上并非如此,那么也不清楚为什么应该为带有 a
307
或302
http 状态代码的回复提供“奇怪”的编码。最近在 nginx 邮件列表中有一个类似的讨论,关于410 Gone
其他错误页面总是被排除在gzip
压缩之外,我认为这种观点在这里同样适用。( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )我有同样的问题通过 html5 视频标签流式传输 mp4 文件。
Safari 和 Firefox 表现正常,而 Chrome 在某些时候触发了 ERR_CONTENT_LENGTH_MISMATCH(但它让我在失败前观看了几分钟的视频)。
关闭 mp4 文件的缓存控制后,问题没有重现。
分享我发布到 SO 的这个答案,以防它有帮助:https ://stackoverflow.com/questions/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
由于未提供块,我在 mp4 播放方面遇到了类似的问题,并根据下面列出的 Apple 指南确认了该问题。我确认我正在下载整个文件,并且在下面的修复之后,只有第一个块。
我通过更改 nginx.conf 中的 gzip 压缩设置来解决我的 Safari .mp4 播放问题,以删除.mp4文件的 gzip 压缩。
这是 nginx 中的块以供参考。(注意:根据您的应用程序的配置方式,您可能需要将位置行更改为
location ~ \.mp4$ {
Apple 文档参考链接:https ://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6