Intereting Posts
Обновить список выбора без обновления Как добавить метки в плагин Chart.js canvas? Отключение входных элементов в форме CakePHP, которая использует компонент безопасности и jQuery jQuery.Deferred (), затем, как разрешить с несколькими параметрами Получение значения из слайдера пользовательского интерфейса jQuery row count не работает должным образом, когда я удаляю строку в строке добавления javascript JavaScript Typeahead Autocomplete соответствует акцентам и тильдам Проблема Предварительно загружать изображения для содержимого AJAX с помощью jQueryUI-вкладок Как я могу установить $ .ajaxStart () и $ .ajaxStop (), чтобы запускать только запросы POST? jQuery проверять меньше, чем jquery / livequery не работает в этом конкретном случае Неисправность получения уникальной подсказки на основе значений оси X в графическом линейном графике clearInterval до setTimeout не работает Настройка фокуса на встроенный элемент Flash-ролика / HTML-вставки с использованием Javascript / jQuery Загрузка json, включая символы новой строки, с помощью данных uri

как получить zip с $ .ajax с php-сервера

Я пытаюсь отправить zip, сгенерированный php-сервером, по запросу jquery $ .ajax.

Это мой код:

PHP:

$file = tempnam($a_folder_path, "zip"); $zip = new ZipArchive(); $zip->open($file, ZipArchive::OVERWRITE); $zip->addFile($path_to_json, 'data.json'); $zip->close(); rename($file, $file . '.zip'); $filename = basename($file . '.zip'); $filepath = $file . '.zip'; while (ob_get_level()) { ob_end_clean(); } header("Pragma: public"); header("Expires: 0"); header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0"); header("Content-Description: File Transfer"); header("Content-type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"".$filename."\""); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($filepath)); ob_end_flush(); echo file_get_contents($filepath); //@readfile($filepath); 

JavaScript:

 $.ajax( { url: myUrl, type: 'POST', data: { "leData" : "some_data" }, context: document.body, cache: false, success: function(data) { console.log(data); console.log(data.length); var bytes = new Uint8Array(data.length); for (var i=0; i<data.length; i++) { bytes[i] = data.charCodeAt(i); } blob = new Blob([bytes], {type: "application/zip"}) saveAs(blob, "test.zip");//trying to access data with FileSave.js zip.load(data);//trying to access data with JSZip.js jsonData = JSON.parse(zip.file('shouldBeThere.json').asText()); }, error: function() { alert('error'); } } ); 

Что просходит:

  1. Сервер создает zip-файл, о котором я прошу, и этот файл не поврежден. Он содержит, среди прочего, shouldBeThere.json.
  2. Сервер отправляет данные во внешний интерфейс.
  3. Консоль.log (данные); line в javascript печатает строку, почти идентичную тому, что я получаю, открывая zip-файл, созданный на сервере, с помощью текстового редактора.
  4. Console.log (data.length); строка в javascript печатает число, меньшее, чем длина содержимого заголовка ответа в соответствии с devroools chrome. Может быть, намек на повреждение данных.
  5. saveAs создает zip, содержащий файл, на который он предназначен, с правильным именем, но когда я пытаюсь разархивировать его, 7zip показывает ошибку: «была сделана попытка переместить указатель файла до начала файла». 6.JSZip, похоже, загружает данные, но тогда zip.file (‘shouldBeThere.json’) имеет значение NULL.

Проблема в том, что я не знаю, возникла ли проблема из php или из javascript. Я не знаю, отправляет ли php поврежденный почтовый индекс, или если javascript не читает его правильно.

Я пробовал все комбинации и методы заголовков php, которые я нашел в Интернете. Я также пытался сделать что-то по-другому в javascript: используя ArrayBuffer вместо Uint8Array, передавая байты вместо данных в zip.load (), используя {type: “application / octet-stream”} в Blob ().

Наконец, я нашел решение: он должен быть указан для ajax для принятого типа данных, а затем преобразовать данные в Unicode в символы. Вот мой новый код javascript:

 $.ajax( { url: myUrl, type: 'POST', data: { "leData" : "some_data" }, context: document.body, cache: false, dataType: 'text', //solution code mimeType: 'text/plain; charset=x-user-defined', //solution code success: function(data) { console.log(data); console.log(data.length); newContent = ""; //solution code for (var i = 0; i < data.length; i++) { //solution code newContent += String.fromCharCode(data.charCodeAt(i) & 0xFF); //solution code } var bytes = new Uint8Array(newContent.length); //modified for (var i=0; i 

Мой PHP-код был в порядке, он даже работал без заголовков. Вот минимальный PHP-код, который мне нужен:

  $file = tempnam($a_folder_path, "zip"); $zip = new ZipArchive(); $zip->open($file, ZipArchive::OVERWRITE); $zip->addFile($path_to_json, 'data.json'); $zip->close(); rename($file, $file . '.zip'); echo file_get_contents($file . '.zip'); 

Решение, вдохновленное этим

Я искал решение для следующей проблемы: «Отправка запроса на php url для создания zip-каталога и загрузка его с помощью ответа ajax».

Следующие работы кода:

Часть PHP для zip:

 // Function for creating a zip of a directory function zipFilesAndDownload($directory, $file_names) { $zip = new ZipArchive(); if ($zip->open("../temp/$directory.zip", ZIPARCHIVE::CREATE) !== TRUE) { exit("Error on creating '../temp/$directory.zip'"); } foreach ($file_names as $file) { $zip->addFile($file, substr($file, strrpos($file, "/") + 1)); } $zip->close(); readfile("../temp/$directory.zip"); unlink("../temp/$directory.zip"); } // Code for creating array of filenames $directory = $_POST['directory']; // eg a directory with ID "123" $dirToZip = "../uploaddir/$directory"; if ($handle = opendir($dirToZip)) { $file_names = array(); while (($file = readdir($handle)) !== false) { if ($file != "." && $file != "..") { array_push($file_names, "$dirToZip/$file"); } } closedir($handle); zipFilesAndDownload($directory, $file_names); } 

Часть JS:

  $(document).on('click', '#downloadDirectory', function () { var directory = '123'; $.ajax({ type: 'POST', url: '../createZip.php', data: {"directory": directory}, dataType: 'text', mimeType: 'text/plain; charset=x-user-defined', success: function (data) { var bytes = new Uint8Array(data.length); for (var i = 0; i < data.length; i++) { bytes[i] = data.charCodeAt(i); } blob = new Blob([bytes], {type: "application/zip"}) saveAs(blob, "pictures.zip"); // "saveAs" function is provided in FileSaver.js } }); });