带有PDF和PHP的Apache2-“此文件不是以“%PDF- \\”开头。

| 数周以来,我一直在寻找导致此错误的原因-而且我还是空白。系统使用PHP生成动态.pdf文件。 我有三台服务器:Dev(使用Apache2的Win7),测试(使用nginx的Ubuntu 10.4)和实时(使用nginx的Ubuntu 10.10)。所有人都在运行php5和我开发的系统-相同的代码。等效,相同的配置。 我已经测试了许多浏览器:DevIE(win7,IE8),DevFF(Win7 Firefox 3.5),DevSaf(win,Safari),LaptopFF(WinXP,Firfox 3.5),笔记本电脑IE(WinXP,IE8 Test(Ubuntu FF3)。 5)和用户(主要是Win 7和Win XP上的IE8)。 当我从“测试”生成PDF时,它在所有浏览器中均可正常运行(除了我无法测试的用户)。 当我从Dev生成PDF时,DevIE,DevFF和DevSaf失败,但是从Test调用它是可行的。 Apache2总是在同一台机器上失败。 在笔记本电脑上,使用FF成功,而使用IE8失败(请参见下文)。 用户正在报告间歇性问题。它失败,然后重复请求并成功。 当失败.... 显示生成的PDF的日志,发送正确的大小回复(500KB至1.8MB),结果为200 OK。有时约10秒后,重复相同的URL-但这会生成登录屏幕(再次返回200 OK),但大小只有2K。这意味着它是在没有cookie的情况下被请求的。 Adobe Reader尝试显示登录页面,并显示不可避免的“ 0”错误消息。 除了当我尝试使用笔记本电脑和IE8时-然后显示源显示空行的4行html文件时显示源失败! 该系统已经运行了一年多-大约2个月前才因更换生产服务器而开始出现故障。测试版本此时未更改,但也开始失败。 我已经尝试过各种头文件,但是我尝试过的一切都没有任何区别。当前的标题集是:
header(\'Content-Disposition: inline; filename=\"\'.$this->pdfFilename().\'\"\');
header(\'Content-type: application/pdf\');
header(\"Pragma: public\");
$when = date(\'r\',time()+20);  // expire in 20 seconds
header(\"Expires: $when\");
我尝试用附件替换内联。添加和删​​除各种无缓存头。一切都无济于事。 通过JavaScript在新窗口中请求PDF,然后8秒钟后进行刷新。我已经测试过,没有新窗口,也没有刷新-没有变化。 我有一些由开发服务器提供的(小)PDF。因此,我提出了我能想到的所有限制。现在,它总是失败。 因此,我有一个Windows Apache2.2服务器,当从同一台计算机浏览时失败,而从Firefox中的其他计算机浏览时成功。 除了浏览器之外,没有涉及代理或缓存机制。 有谁对出什么问题有任何想法吗?就像我说的那样,我已经进行了将近4周的测试和排除,无论是断断续续的,甚至还没有发现故障的组件。     
已邀请:
这真的很难解决-对于初学者,(请原谅我的直言,但是)这是管道不应该是什么样的一个典型示例: 三种不同的操作系统。 可能至少有两个不同版本的PHP。 两个不同的Web服务器。 但是无论如何,有关调试PHP的一些一般性提示: 确保在
php.ini
中启用
error_log
log_errors
(设置
display_errors = Off
) 使用最冗长的
error_reporting
在nginx中设置
access_log
error_log
。 在nginx中提高日志级别(我猜您使用的是php-cgi或php-fpm,因此您应该能够查看下载尝试失败时后端发出的状态)。 此外: 您尚未共享PDF的生成方式-您确定此处使用的所有库在所有系统中都是相同的,或至少在某种程度上是相同的吗? 无论如何,只是为了确保在提供下载之前,我会将PDF保存在服务器上。这使您可以对实际文件进行故障排除-查看PDF生成是否确实有效。 由于您要保存PDF,因此可以将其放在公共文件夹中,这样您就可以查看是否可以在生成PDF后直接重定向到该PDF。而且只有在这种方法可行的情况下,我才能进行强制下载。 我将在所有阶段复制生产环境。 ;-)您需要开发服务器完全类似于生产环境。对于您自己的工作站,我建议您使用VM(例如,通过带有Ubuntu 10.10的Virtualbox)。 让我知道这可以带您到某个地方,然后回复更新。 :-) 更新: 我将调查以下两个标题:
header(\"Cache-Control: no-cache, must-revalidate\"); // HTTP/1.1
header(\"Expires: Sat, 26 Jul 1997 05:00:00 GMT\"); // Date in the past
绝对有助于消除缓存。     
这些是标头,这些标头终于在我的一个应用程序中以类似情况工作:
header(\"Pragma: public\");
header(\"Expires: 0\");
header(\"Cache-Control: must-revalidate, post-check=0, pre-check=0\");
header(\"Cache-Control: private\",false);
header( \"Content-Type: application/pdf\" );
header(\"Content-Disposition: inline; filename=\\\"YourPDF_\" . time() . \".pdf\\\";\");
header(\"Content-Transfer-Encoding: binary\");
header(\"Content-Length: \". strlen( $pdfData ) );
我添加了time()代码以使文件名每次都更改,以便它可能通过所有代理。 有时但很少出现该问题。然后,我们要求客户使用浏览器上下文菜单下载文件。 PS:该应用程序使用的ezPDF可在此处找到:http://www.ros.co.nz/pdf/     

要回复问题请先登录注册