Я очень опоздал на вечеринку, но я поставлю это здесь, если кто-то еще захочет узнать мое решение:
У меня была настоящая борьба с этой точной проблемой, но я нашел жизнеспособное решение, используя iframes (я знаю, я знаю. Это ужасно, но это работает для простой проблемы, которая у меня была)
У меня была html-страница, которая запустила отдельный скрипт php, который сгенерировал файл, а затем загрузил его. На html-странице я использовал следующий jquery в html-заголовке (также необходимо включить библиотеку jquery):
<script>
$(function(){
var iframe = $("<iframe>", {name: 'iframe', id: 'iframe',}).appendTo("body").hide();
$('#click').on('click', function(){
$('#iframe').attr('src', 'your_download_script.php');
});
$('iframe').load(function(){
$('#iframe').attr('src', 'your_download_script.php?download=yes'); <!--on first iframe load, run script again but download file instead-->
$('#iframe').unbind(); <!--unbinds the iframe. Helps prevent against infinite recursion if the script returns valid html (such as echoing out exceptions) -->
});
});
</script>
В your_download_script.php укажите следующее:
function downloadFile($file_path) {
if (file_exists($file_path)) {
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=' . basename($file_path));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
ob_clean();
flush();
readfile($file_path);
exit();
}
}
$_SESSION['your_file'] = path_to_file; //this is just how I chose to store the filepath
if (isset($_REQUEST['download']) && $_REQUEST['download'] == 'yes') {
downloadFile($_SESSION['your_file']);
} else {
*execute logic to create the file*
}
Чтобы разобраться, jquery сначала запускает ваш php-скрипт в iframe. Iframe загружается после создания файла. Затем jquery снова запускает скрипт с переменной запроса, сообщающей скрипту о загрузке файла.
Причина, по которой вы не можете выполнять загрузку и генерацию файлов сразу, связана с функцией php header (). Если вы используете header (), вы изменяете скрипт на что-то отличное от веб-страницы, и jquery никогда не распознает загружаемый скрипт. Я знаю, что это не обязательно обнаруживает, когда браузер получает файл, но ваша проблема звучит похоже на мою.