PHP ob_gzhandler,设置 Content-Length 禁用 gzip 压缩输出

标签 php gzip content-length content-encoding transfer-encoding

我阅读了一些有关设置将提供的文件的内容长度的文章。与分块下载相比,它有一些好处。当内容长度未知时,服务器提供 block (无论如何都不知道 block 的大小是多少)。

在 PHP 中,我使用 ob_gzhandler 来 gzip html、js 和 css 文件以及其他基于文本的内容。在 gzip 输出之前设置原始 content-length 会导致奇怪的副作用,因为长度与 gzip 输出的长度不匹配。我注意到有延迟或浏览器报告编码错误。

我看到了一个技巧(也在 stackoverflow 上),可以在 gzip 压缩后设置内容长度,以确保它报告正确的大小。但是当我这样做时,内容不再被压缩。

问题是,这种行为正确吗?gzip 压缩的内容是否总是以分块形式发送?仅未 gzip 压缩的文件才需要内容长度吗?

这里是一些代码片段:

1 导致 gzip 压缩和分块文件传输:

ob_start('ob_gzhandler');
echo $sResult;

2 导致指定内容长度的正常文件传输(但需要 gzip 压缩和内容长度):

ob_start('ob_gzhandler');
echo $sResult;
header('Content-Length: '.ob_get_length()); 

这里是一些http header结果的图片: 1 Gzipped and Chuncked

2 Expect Gzipped but normal transfer when set content-length

最佳答案

在这里找到解决方案/技巧: How to determine the Content-Length of a gzipped file?

做成这样:

// clear output buffers
while( ob_get_level() )
 { ob_end_clean(); }

< send http headers here >

ob_start();
ob_start('ob_gzhandler');
echo $sResult;
if( !headers_sent() )
{
   ob_end_flush(); // Flush the output from ob_gzhandler
   header('Content-Length: '.ob_get_length());
   ob_end_flush(); // Flush the outer ob_start()
}

对我来说,不清楚为什么会这样,但似乎效果很好。内容现已被 gzip 压缩并具有内容长度(未分块)。

为了证明这一点,这是一个屏幕截图:

gzipped and content-length

干杯! ;-)

关于PHP ob_gzhandler,设置 Content-Length 禁用 gzip 压缩输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20332598/

相关文章:

php - SQL 错误:mysqli_stmt::bind_param():类型定义字符串中的元素数量与绑定(bind)变量的数量不匹配

php - 什么是多部分二进制输入?

postgresql - 如何使用 jdbc API 在 java 中为 postgresql 数据库执行 sql gzipped 脚本?

node.js - Axios:请求 header 中缺少内容长度 header

php - 强制网络浏览器播放文件而不是下载

c# - 如何在 C# 中复制 PHP 的 PRNG 算法实现?

hadoop - hadoop的gzip与tar -zvcf不同吗?

java - 使用 gzip 格式的缓冲区解压缩图像失败

java - 来自 HTTP 客户端的 PUT 请求后获取 "411 Length Required"

IIS7 - 在 ASP 中指定内容长度 header 会导致 "connection reset"错误