2009-10-09 136 views
0

我在一個很好的「強制下載文件」腳本上工作,目的是確保提供下載文件而不是顯示在瀏覽器中,無論文件類型是什麼。強制下載腳本

它曾經運行良好,但最近我收到反饋,它不會工作,特別是對於PDF和xls文件(MS Excel)。在PDF的情況下,該文件被檢測爲「無效」,或者在xls文件的情況下,該文件在其內容的頂部獲得部分html文件目錄頁面。

我的功能到底出了什麼問題?

這是它。請注意,它可以使用url或本地路徑工作。

function offerToDownloadFile($filename, $access_type='url') { 
    /* 
    PHP FORCE DOWNLOAD SCRIPT 
    */ 

    // required for IE, otherwise Content-disposition is ignored 
     if (ini_get('zlib.output_compression')) 
      ini_set('zlib.output_compression', 'Off'); 

     if($access_type === 'url') { 
     // access type is via the file 's url 
      $parsed_url = parse_url($filename); 
      $fileinfo = pathinfo($filename); 
      $parsed_url['extension'] = $fileinfo['extension']; 
      $parsed_url['filename'] = $fileinfo['basename']; 
      $parsed_url['localpath'] = LOCALROOT . $parsed_url['path']; 
     } 
     else { 
     // access type is the local file path 
      $fileinfo = pathinfo($filename); 
      $parsed_url['localpath'] = $filename; 
      $parsed_url['filename'] = basename($filename); 
      $parsed_url['extension'] = $fileinfo['extension']; 
     } 


     // just in case there is a double slash created when joining document_root and path 
     $parsed_url['localpath'] = preg_replace('/\/\//', '/', $parsed_url['localpath']); 

     if (!file_exists($parsed_url['localpath'])) { 
      die('File not found: ' . $parsed_url['localpath']); 
     } 
     $allowed_ext = array('ics','pdf', 'png', 'jpg', 'jpeg', 'zip', 'doc', 'xls', 'gif', 'exe', 'ppt','ai','psd','odt'); 
     if (!in_array($parsed_url['extension'], $allowed_ext)) { 
      die('This file type is forbidden.'); 
     } 

     switch ($parsed_url['extension']) { 
      case "ics": $ctype="text/calendar"; 
       break; 
      case "pdf": $ctype = "application/pdf"; 
       break; 
      case "exe": $ctype = "application/octet-stream"; 
       break; 
      case "zip": $ctype = "application/zip"; 
       break; 
      case "doc": $ctype = "application/msword"; 
       break; 
      case "xls": 
       $ctype = "application/vnd.ms-excel"; 
       break; 
      case "ppt": $ctype = "application/vnd.ms-powerpoint"; 
       break; 
      case "gif": $ctype = "image/gif"; 
       break; 
      case "png": $ctype = "image/png"; 
       break; 
      case "jpeg": 
      case "jpg": $ctype = "image/jpg"; 
       break; 
      default: $ctype = "application/force-download"; 
     } 
     header("Pragma: public"); // required 
     header("Expires: 0"); 
     header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
     header("Cache-Control: private", false); // required for certain browsers 
     header("Content-Type: $ctype"); 
     header("Content-Disposition: attachment; filename=\"" . $parsed_url['filename'] . "\";"); 
     header("Content-Transfer-Encoding: binary"); 
     // header("Content-Length: " . filesize($parsed_url['localpath'])); 
     readfile($parsed_url['localpath']); 
     clearstatcache(); 
     die(); 
     exit(); 
    } 
+0

你有什麼瀏覽器這個問題?這是全部嗎? – Pasta 2009-10-09 10:32:35

+0

也使用'application/octet-stream'作爲默認媒體類型。 – Gumbo 2009-10-09 12:16:48

回答

1

該腳本現在可用。我不得不使這個頭()調用。我不知道爲什麼,這是試驗和錯誤,導致我找到了這個解決方案。

header("Content-Type: $ctype"); 
header("Content-Disposition: attachment; filename=\"" . $parsed_url['filename'] . "\";"); 
header("Content-Transfer-Encoding: binary"); 
header('Accept-Ranges: bytes'); 
header("Cache-control: private"); 
header('Pragma: private'); 
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
1

強制文件,而不是被看作被下載近於不可能的,無論你如何處理它實現 - 第三方組件,如Adobe的PDF查看器可以直接強制的東西忽略內容處置頭和做什麼它喜歡。如果你與公衆打交道,你必須接受用戶將採取的數據,他們或他們的軟件,而不是你的網站將決定他們如何使用它。

+0

這是我們學校的外聯網。所以它是一個廣泛的受衆(約1000人)。我現在擔心的是文件不被檢測爲無效。偶爾在瀏覽器中查看它而不是我的預期下載不是一個問題。 – pixeline 2009-10-09 08:09:43

0

我不知道這是否會在所有幫助,但可以嘗試在下列頭以及:

header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 

與MS和PDF(和許多其他)問題是他們被迫與被打開3PP軟件如MS Excel,並且忽略了Content-Disposition。

如果上述不起作用,用戶必須右鍵單擊並選擇另存爲;可能不是您的問題的最佳解決方案。

0

它可能是值得考慮的.htaccess替代強制下載,例如:

AddType application/octet-stream csv 
AddType application/octet-stream pdf 
AddType application/octet-stream xls