PHP:渲染大图像的问题(错误321)

时间:2010-12-29 12:01:54

标签: php image apache rendering

再次提出我的php问题:)

以下是我的PHP脚本的一部分,它正在渲染JPEG图像。

...
$tf=$requested_file;
$image_type="jpeg";
header("Content-type: image/${image_type}");
$CMD="\$image=imagecreatefrom${image_type}('$tf'); image${image_type}(\$image);";
eval($CMD);
exit;
...

没有语法错误,因为上面的代码适用于小图像,但对于大图像,它给出:

Error 321 (net::ERR_INVALID_CHUNKED_ENCODING): Unknown error.在浏览器中。

可以肯定的是,我使用来自同一源图像的imagemagick创建了两个图像 - 一个调整为原始的10%和其他90%。

http://mostpopularsports.net/images/misc/ttt10.jpg有效

http://mostpopularsports.net/images/misc/ttt90.jpg在浏览器中显示错误301。

OP在Error writing content through Apache发布的解决方案存在一个相关问题,但我无法理解如何进行修复。有人可以帮我吗?

我查看了Chrome中的标题。对于第一个请求,一切都很好。对于第二个请求 - 请求标头都是乱码。


两个图像都是 jpeg(因为它们是从imagemagick创建的。但仍然要确保我已经检查过):

misc/ttt10.jpg: JPEG image data, JFIF standard 1.01
misc/ttt90.jpg: JPEG image data, JFIF standard 1.01

最后,我修复的方法是,从响应中删除Transfer-Encoding: chunked标头。 [此标题仅在数据足够大时由apache发送]。 (我有一个内部代理,所以在代理脚本中也是如此 - 否则可能需要在apache设置中执行此操作。)

有一些很好的答案,我选择了帮助我最好地解决问题的答案。

感谢

JP

3 个答案:

答案 0 :(得分:1)

我不会直接回答你的问题,但我必须说一下你对eval的使用,这在这种情况下是非常不必要的(就像在其他所有情况一样)。

你可以这样做,避免在腿上射击自己:

header("Content-type: image/${image_type}");
$image = imagecreatefromstring(file_get_contents($tf));
switch($image_type) {
    case 'jpeg':
    case 'jpg':
        imagejpeg($image);
        break;
    case 'png':
        imagepng($image);
        break;
    case 'gif':
        imagegif($image);
        break;
}

答案 1 :(得分:1)

目前,您始终将内容类型标题发送为JPEG,即使图像可能是其他内容(PNG / GIF?)。这也可能会带来一些麻烦。

另外,你真的不应该像这样使用eval。你想要实现什么目标?

答案 2 :(得分:0)

您应该使用netcat调试确切的服务器响应。但是使用wget --save-headers快速查看显示输出实际上看起来没问题:

HTTP/1.1 200 OK
Date: Wed, 29 Dec 2010 12:16:03 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.2.6-3ubuntu4.6
Set-Cookie: PHPSESSID=sjh4k63i9npk6b15uperclau75; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive, Keep-Alive
Transfer-Encoding: chunked
Content-Type: image/jpeg

您的链接错误报告包含无效的“分块,分块” - 这与您的脚本不同。仍然存在分块编码问题,因为您的Chrome错误消息会显示。

我认为问题可能是PHP输出缓冲区。 transfer-encoding缺少最终0\r\n来终止HTTP流。

您可以尝试flush(),禁用PHP输出缓冲区,以及Apaches mod_deflate(这是一个额外的缓冲区)。我对于为什么PHP保持连接打开一无所知,但它很可能是eval和exit的特定组合。尝试重写代码:

header("Content-type: image/${image_type}");
flush();
$func = "imagecreatefrom${image_type}";
$image = $func($tf);
$func = "image${image_type}";
$func($image);
flush();
exit;

或者如果它不起作用。尝试在图像后输出垃圾echo "0";