PHP для загрузки ZIP-файла работает при вызове напрямую, но не из веб-приложения - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть PHP-код, который создает zip-файл и делает его доступным для загрузки из браузера.Часть загрузки выглядит следующим образом:

download.php

// force client download
if (headers_sent()) {
    echo 'HTTP header already sent';
} else {
    if (!is_file($zipFile)) {
    header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
    echo $zipFile . ' not found';
    } else if (!is_readable($zipFile)) {
        header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
        echo $zipFile . ' not readable';
    } else {
        ob_start();
        // http headers for zip downloads
        header('Content-Description: File Transfer');
        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="' . $zipName . '"');
        header('Content-Transfer-Encoding: binary');
        header('Connection: Keep-Alive');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');

        set_time_limit(0);
        ob_flush();
        ob_clean();
        readfile($zipFile);
    }
}

При вызове из браузера, например, localhost/download.php, он работает и заставляет меня правильно загрузить ZIP-файл.

Однако мне нужно вызвать его из моего веб-приложения JS.

Я вызываю его с помощью запроса POST AJAX, который выглядит следующим образом:

var xhr;
if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // all browsers
else xhr = new ActiveXObject("Microsoft.XMLHTTP"); // for IE

var php_url = '/localhost/download.php' // ?wfs_url=' + url + 'format=' + format_list[0];
// (https://stackoverflow.com/a/53982364/1979665)
var formData = new FormData();
formData.append('wfs_url', url);
formData.append('format', format_list[0]);
xhr.open('POST', php_url);
xhr.onreadystatechange = function () {
    if (xhr.readyState===4 && xhr.status===200) {
        alert('Server reply: ' + xhr.responseText);
    }
}
xhr.send(formData);

return false;

Код срабатывает, когда я нажимаю на кнопку.

Видимо, он что-то делает.Промежуточные выходы PHP (некоторые папки) созданы правильно, но загрузка не начинается.

Часть alert('Server reply: ' + xhr.responseText); показывает странное сообщение с некоторыми грязными символами, которое, как я полагаю, происходит из файлов, созданных и прочитанных кактекст как-то.

Вот скриншот сообщения:

enter image description here

Ответы [ 2 ]

0 голосов
/ 02 января 2019

После выбора опции 2 в @Gabriel принял ответ, я смог заставить свой код работать.Вот модифицированная версия JS (я не внес никаких изменений в код PHP):

var php_url = '/localhost/download.php' // ?wfs_url=' + url + 'format=' + format_list[0];
// (https://stackoverflow.com/a/53982364/1979665)
var formData = new FormData();
formData.append('wfs_url', url);
formData.append('format', format_list[0]);
xhr.open('POST', php_url);
xhr.onreadystatechange = function () {
    if (xhr.readyState===4 && xhr.status===200) {
        var blob = new Blob([xhr.response], { // SOLUTION
            type: "application/zip", // SOLUTION
        }); // SOLUTION
        var filename = "test.zip"; // SOLUTION
        if (navigator.msSaveOrOpenBlob) { // SOLUTION
            navigator.msSaveOrOpenBlob(blob, filename); // SOLUTION
        } else { // SOLUTION
            var a = document.createElement("a"); // SOLUTION
            document.body.appendChild(a); // SOLUTION
            a.style = "display:none"; // SOLUTION
            var url = window.URL.createObjectURL(blob); // SOLUTION
            a.href = url; // SOLUTION
            a.download = filename; // SOLUTION
            a.click(); // SOLUTION
            window.URL.revokeObjectURL(url); // SOLUTION
            a.remove(); // SOLUTION
         } // SOLUTION
    }
}
xhr.responseType = "arraybuffer"; // SOLUTION
xhr.send(formData);
0 голосов
/ 31 декабря 2018

PHP-скрипт отправляет фактический двоичный источник zip-файла, в то время как запрос AJAX пытается отобразить его в виде текста, это мусор , который вы получите.

Если вы действительноесли вы хотите сохранить AJAX (было бы проще сделать <form>, который отправляется на download.php), вы можете сделать одну из двух вещей:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...