带有 PDF 和 PHP 的 Apache2 - "此文件不以 "%PDF-" 开头



我一直试图找到这个错误的原因几个星期了-我已经出现了一个空白。系统使用PHP生成动态的。pdf文件。

我有三个服务器:Dev (Win7 with Apache2), Test (Ubuntu 10.4 with nginx)和Live (Ubuntu 10.10 with nginx)。都是运行php5和我开发的系统-相同的代码。等价,相同的配置。

我测试过很多浏览器:设备(win7, IE8), DevFF (win7 Firefox 3.5), DevSaf (win, Safari), LaptopFF (WinXP, Firfox 3.5),笔记本IE(WinXP, IE8 Test (Ubuntu FF3.5))和用户(主要是在win7和win XP上的IE8)。

  • 当我从测试中生成PDF时,它在所有浏览器中都能正常工作(除了我无法测试的用户)。
  • 当我从Dev生成PDF时,它从device, DevFF和DevSaf失败,但从Test调用它有效。
  • Apache2总是在同一台机器上失败。
  • 在笔记本电脑上,使用FF成功,使用IE8失败(见下文)。

用户正在报告间歇性问题。它失败了,然后重复请求,它成功了。

失败时....

显示了生成PDF的日志,发送正确大小的回复(500KB到1.8MB),结果为200 OK。这是,有时大约10秒后会重复相同的URL -但这会生成登录屏幕(同样是200 OK回复),但大小只有2K。这意味着它是在没有cookie的情况下被请求的。

adobereader尝试显示登录页面,不可避免地出现"This file does not start with "%PDF-"错误消息。

除了当我尝试与笔记本电脑和IE8 -然后它失败了显示源显示4行html文件与一个空的身体!

这个系统已经工作了一年多了,直到两个月前更换了生产服务器才开始出现故障。测试版本在这个时候没有改变,但也开始失败。

我已经尝试了各种各样的头,但我所尝试的没有任何不同。当前的标题集是:

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");

我已经尝试用附件替换内联。添加和删除各种无缓存头。一切都无济于事。

PDF是在一个新的窗口中请求的,通过JavaScript -并在8秒后刷新。我在没有新窗口和刷新的情况下进行了测试——没有变化。

我有几个(小)pdf由Dev服务器服务。所以我已经提高了所有我能想到的极限。现在它总是失败。

所以我有一个Windows Apache2.2服务器,在同一台机器上浏览时失败,在Firefox中从其他机器上浏览时成功。

除了浏览器中的代理或缓存机制之外,没有其他代理或缓存机制。

有谁知道是哪里出了问题吗?正如我所说,我已经测试和删除了将近4周的东西,断断续续,我甚至还没有发现失败的组件。

这真的很难排除故障-对于初学者来说,(请原谅我的直率,但是)这是管道不应该是什么样子的主要示例:

  • 三个不同的操作系统。
  • 可能至少有两个不同的PHP版本。
  • 两个不同的web服务器。

但无论如何,一些调试PHP的一般提示:

  • 确保php.ini中的error_loglog_errors(设置display_errors = Off)
  • 使用最详细的error_reporting
  • 设置access_logerror_log在nginx.
  • 在nginx中启动日志级别(我猜你使用php-cgi或php-fpm,所以你应该能够看到下载尝试失败时后端发出的状态)。

此外:

  1. 你没有分享PDF是如何生成的-你确定这里使用的所有库在所有系统中都是相同的,或者至少在某种程度上是相同的吗?
  2. 无论如何,只是为了确保在提供下载之前我将PDF保存在服务器上。这允许您对实际文件—查看PDF生成是否有效。
  3. 既然你在保存PDF,我想把它放在公共文件夹,所以你可以看看你是否可以在它生成后重定向到它。只有这样,我才会去做强制下载之类的事情。
  4. 我会在所有阶段复制生产环境。-)你需要你的开发服务器完全像生产环境。对于你自己的工作站,我推荐一个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/

最新更新