2011-04-17 157 views
3

我一直在試圖找到這個錯誤的原因現在幾個星期了 - 我已經提出了一個空白。該系統使用PHP來生成動態的.pdf文件。我有三臺服務器:Dev(Win7和Apache2),Test(Ubuntu 10.4和nginx)和Live(Ubuntu10.10和nginx)。所有運行php5和我開發的系統 - 相同的代碼。等同,相同的配置。 (win7,IE8),DevFF(Win7 Firefox 3.5), DevSaf(win,Safari),LaptopFF(WinXP,Firfox 3.5),Laptop IE(WinXP,IE8)我有很多瀏覽器, 測試(Unbuntu FF3.5)和用戶(主要是IE8在Win 7和Win XP)。Apache2與PDF和PHP錯誤

  • 當我生成測試它正常工作在所有瀏覽器(除了我無法測試用戶一個PDF )
  • 當我從Dev生成一個PDF時,它將失敗DevIE,DevFF和DevSaf,但是從測試工作中調用它。
  • Apache2總是失敗s來自同一臺機器。
  • 從筆記本電腦,使用FF成功,並使用IE8失敗(見下文)。

用戶正在報告間歇性問題。它失敗,然後重複請求併成功。

當它失敗....

生成的PDF的日誌中所示,發送正確的類尺寸答覆(500KB到1.8MB)用200 OK結果。這是有時約10秒後跟着重複相同的URL - 但這會生成登錄屏幕(再次200 OK回覆),但只有2K的大小。其含義是,它沒有cookie的要求。

Adob​​e Reader嘗試顯示登錄頁面,並顯示不可避免的"This file does not start with "%PDF-"錯誤消息。

除了當我嘗試使用筆記本電腦和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"); 

我試過用附件替換內聯。添加和刪​​除各種no-cache 標題。一切都無濟於事。

PDF是在新窗口中通過javascript進行請求的,並且在8秒後進行刷新。我沒有新窗口進行測試,沒有刷新 - 沒有改變。

我有一些由開發服務器提供的(小)PDF文件。所以我提出了我所能想到的每個極限 的。現在它總是失敗。

所以我有一個Windows Apache2.2服務器,當從同一臺機器瀏覽時失敗,併成功從Firefox中的其他機器瀏覽時成功。

在瀏覽器中沒有涉及代理或緩存機制。

有沒有人有什麼想法可能會出錯?正如我所說,我現在一直在測試和消除將近4周的事情,並且我還沒有發現失敗的組件。

+0

一些更多的輸入。測試了我妻子的Win7機器上的Dev服務器 - 一切正常。它看起來好像它是與64位窗口7. – Ian 2011-04-17 18:30:19

+0

是它確定標題導致一個問題或可能會出現代碼的pdf生成部分的錯誤? – bumperbox 2011-04-18 11:39:26

+0

當使用FF,使用FF和IE8的32位Windows 7以及服務器是nginx和fast-cgi時,從Linux進行瀏覽時,PDF內容是正確的。所以我認爲這是正確的。如果標題錯了,它將無法工作。爲什麼重複日誌在10秒後來到?實際上,PDF將在顯示時生成並提供1到2秒的時間 - 但在失敗時需要10秒鐘才能失敗。仍然感到困惑。 – Ian 2011-04-18 16:10:52

回答

3

這是非常艱難的排查 - 對於初學者來說,(請原諒我的直率,但)這是什麼管道不應該看起來像一個典型的例子:

  • 三種不同的操作系統。
  • 可能至少有兩個不同版本的PHP。
  • 兩個不同的web服務器。

但無論如何,在調試PHP幾個一般提示:

  • 請確保啓用error_logphp.inilog_errors(設置display_errors = Off
  • 使用最詳細的error_reporting
  • 設置access_log和在nginx中爲error_log
  • 在nginx中調整日誌級別(我猜你使用了php-cgi或php-fpm,所以當下載嘗試失敗時你應該能夠看到後端發出的狀態)。

此外:

  1. 您還沒有共享如何生成PDF - 你確定這裏使用的所有庫都相同或至少在某種程度上同在所有系統?
  2. 無論如何,只要確保我將PDF保存在服務器上之前,它是提供的下載。這使您可以排查實際文件—以查看PDF生成是否真正起作用。
  3. 既然你保存PDF,我看到把它在一個公共文件夾,所以你可以看到,如果它產生後,你可以重定向到它。只有這樣做,那麼我會努力下載某種東西。
  4. 我會在所有階段複製生產環境。 ;-)你需要你的開發服務器完全像生產環境。對於自己的工作站,我建議一個虛擬機(例如,通過VirtualBox虛擬與Ubuntu 10.10)。

讓我知道這讓你的地方,並用更新的回覆。 :-)

更新

我調查這些兩個頭:

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past 

與緩存清除絕對好用。

+0

同意所有計數,第2點是必須的做清除與PDF生成本身的任何問題.. – Ben 2011-04-21 00:16:12

+0

真的很好,務實的建議。同意@Ben - 點2是你的下一件事。 ++ – 2011-04-21 06:09:42

+0

謝謝直到 - Ecellent建議。選項2後跟選項3是我開發它的方式,因此可以切換回來。 PDF使用http://www.ros.co.nz/pdf版本009進行生成,並在所有機器上使用完全相同的代碼。切換到10.10位於待辦事項列表中 - 生產開關由兩週前的硬盤崩潰觸發。在生產中使用Ubuntu 10:04時,問題發生率大致相似。 – Ian 2011-04-21 08:23:27

0

這些都是頭部,這終於在類似的情況在我的應用程序的一個工作:

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

我加入的時間()代碼,以使文件名每次更改,所以它可能通過所有代理。

時不時重新出現問題。然後,我們要求我們的客戶使用瀏覽器上下文菜單下載文件。

PS:應用程序使用ezPDF在這裏找到:http://www.ros.co.nz/pdf/

+0

Stackoverflow莫名其妙地不讓我評論,所以我將標題添加到了我的答案中。 – Till 2011-04-21 22:24:49

+0

謝謝@Till。我會將你的標題添加到當前的標題中。 – SteAp 2011-04-21 22:58:15