【发布时间】:2011-07-07 16:50:47
【问题描述】:
服务器设置:Apache 2.2.14、PHP 5.3.1
我使用 PHP 脚本来提供所有类型的文件,作为具有复杂访问权限的应用程序的一部分。到目前为止,一切进展顺利,但我们的一位测试版用户用 10 兆像素的数码相机拍了一张照片并上传了它。它位于 9 MB 以北的某个地方,9785570 字节。
出于某种原因,在 Safari 中(到目前为止,仅在 Safari 中,我已在 5.0.5 上复制了此内容)下载有时会中途挂起并且永远不会完成。 Safari 只是继续愉快地尝试永远加载。我无法始终如一地重现该问题 - 如果我一遍又一遍地重新加载,有时下载会完成,有时不会。没有明显的规律。
我正在监视服务器访问日志,在 Safari 挂起的情况下,我在离开页面或取消页面加载后看到相应文件大小的 200 响应,但之前没有。
这是为文件提供服务的代码,包括标题。当下载成功并检查标题浏览器端时,我看到内容类型和大小已正确设置。我的标题中有什么吗? Safari中的东西?两个都?
header('Content-Type: ' . $fileContentType);
header('Content-Disposition: filename=' . basename($fpath));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($fpath));
ob_clean();
flush();
session_write_close();
readfile($fpath);
exit;
作为事件保证的其他公告:
通过人为地将下载速度限制为 256k/s -- 即将文件分成 256k 块并在提供它们之间暂停,如
$chunksize = 1 * (256 * 1024); // how many bytes per chunk
if ($size > $chunksize) {
$handle = fopen($fpath, 'rb');
$buffer = '';
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
sleep(1);
}
fclose($handle);
} else {
readfile($fpath);
}
我能够保证图像文件在任意条件下都能在 Safari 中成功显示。
512k 的块大小并不能保证显示成功。
我几乎可以肯定这里的问题是 Safari 的图像渲染器无法更快地处理传入的数据,但是:
- 我很想知道
- 我还想知道是否有其他类型的解决方法,例如特殊的 CSS webkit 属性或任何处理大图像的方法,因为 256k/秒对于 10 MB 文件来说有点可怕。
更奇怪的是,使用 usleep() 设置更细粒度的睡眠会导致睡眠时间为 500 毫秒而不是 750 毫秒时出现问题。
【问题讨论】:
-
您是否尝试(重新)将 php 执行超时 (php.net/manual/en/function.set-time-limit.php) 设置为较大的值以排除执行时间作为潜在问题?
-
是的。当时间限制设置为 300 时,Safari 仍然行为不端,但在我的连接上,文件只需要一两秒即可提供服务。
标签: php apache safari download