2009-10-09 7 views
0

J'ai travaillé sur un joli script "force download file" qui a pour but de s'assurer que les fichiers sont proposés au téléchargement au lieu d'être affichés dans le navigateur, quel que soit le type de fichier.force script de téléchargement

Cela fonctionnait bien mais récemment j'ai reçu des commentaires que cela ne fonctionnerait pas, notamment pour les fichiers pdf et xls (MS Excel). Le fichier est soit détecté comme "invalide" dans le cas du fichier PDF, soit fait partie de la page du répertoire du fichier html en plus de son contenu dans le cas du fichier xls.

Qu'est-ce qui ne va pas exactement avec ma fonction?

La voici. Notez qu'il peut fonctionner avec une URL ou un chemin local.

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

Quels navigateurs ont ce problème-vous? C'est tout? – Pasta

+0

Utilisez également 'application/octet-stream' comme type de média par défaut. – Gumbo

Répondre

1

Le script fonctionne maintenant. J'ai dû faire ce header() à la place. Je ne sais pas vraiment pourquoi, c'est l'essai et l'erreur qui m'ont conduit à cette solution.

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

fichiers Obliger à télécharger, par opposition à vue est proche sur impossible à réaliser, peu importe la façon dont vous manipulez - composants 3ème partie comme visionneuse de PDF d'Adobe peut simplement forcer les choses à ignorer les en-têtes Content-Disposition et faire ce que il aime. Si vous traitez avec le grand public, vous devez accepter que les utilisateurs prennent les données et eux ou leur logiciel pas votre site Web déterminera comment ils l'utilisent.

+0

c'est pour l'extranet de notre école. C'est donc un large public (environ 1000 personnes). Ce que je suis préoccupé en ce moment, c'est que le fichier ne soit pas détecté comme invalide. Que ce soit vu de temps en temps dans le navigateur au lieu de mon téléchargement prévu n'est pas une préoccupation. – pixeline

0

Je ne suis pas sûr que cela contribuerait à tout, mais essayez de mettre en-têtes suivants ainsi:

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

Le problème avec MS et PDF (et bien d'autres) est qu'ils sont contraints d'être ouvert avec Logiciel 3PP comme MS Excel par exemple et ignorent Content-Disposition.

Si l'option ci-dessus ne fonctionne pas, les utilisateurs devront cliquer avec le bouton droit de la souris et sélectionner Enregistrer sous; probablement pas la meilleure solution pour votre problème.

0

il peut être utile d'envisager une alternative .htaccess pour forcer le téléchargement, par exemple:

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