0 votes

forcer le téléchargement du script

J'ai travaillé sur un joli script "force download file" dont le but est de s'assurer que les fichiers sont proposés au téléchargement plutôt qu'affichés dans le navigateur, quel que soit le type de fichier.

Il fonctionnait bien auparavant, mais j'ai récemment reçu des commentaires indiquant qu'il ne fonctionnait pas, notamment pour les fichiers pdf et xls (MS Excel). Le fichier est soit détecté comme "invalide" dans le cas du PDF, soit reçoit une partie de la page du répertoire du fichier html par-dessus son contenu dans le cas du fichier xls.

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

C'est ici. Notez que cela peut fonctionner soit avec une url soit avec 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();
    }

1voto

squeeks Points 1210

Il est pratiquement impossible d'obliger les fichiers à être téléchargés plutôt qu'à être visualisés, quelle que soit la façon dont vous le faites. Des composants tiers comme le PDF Viewer d'Adobe peuvent simplement forcer les choses à ignorer les en-têtes Content-Disposition et faire ce qu'ils veulent. Si vous traitez avec le grand public, vous devez accepter que les utilisateurs prennent les données et que ce sont eux ou leurs logiciels, et non votre site web, qui déterminent comment ils les utilisent.

0voto

David Kuridža Points 2395

Je ne sais pas si cela peut vous aider, mais essayez également de mettre les en-têtes suivants :

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 beaucoup d'autres) est qu'ils sont forcés d'être ouverts avec des logiciels 3PP comme MS Excel par exemple et ignorent Content-Disposition.

Si ce qui précède ne fonctionne pas, les utilisateurs devront faire un clic droit et sélectionner Enregistrer sous ; ce n'est probablement pas la meilleure solution pour votre problème.

0voto

pixeline Points 8713

Le script fonctionne maintenant. J'ai dû faire ces appels header() à la place. Je ne sais pas vraiment pourquoi, ce sont des essais et des erreurs 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");

0voto

seengee Points 9367

Il peut être intéressant 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X