PHP генерирует файл для загрузки, а затем перенаправляет
У меня есть PHP-приложение, которое создает CSV-файл, который принудительно загружается с использованием заголовков. Вот соответствующая часть кода:
header('Content-Type: application/csv');
header("Content-length: " . filesize($NewFile));
header('Content-Disposition: attachment; filename="' . $FileName . '"');
echo $content;
exit();
Что я хотел бы сделать, так это перенаправить пользователей на новую страницу после создания файла и отправки запроса на загрузку. Простое добавление header("Location: /newpage")
в конец, как и ожидалось, не сработало, поэтому я не уверен, как это подстроить.
10 answers
Я не думаю, что это можно сделать, хотя я не уверен на 100%.
Обычно (например, на популярных сайтах загрузки) происходит обратное: сначала вы переходите на страницу после , а затем начинается загрузка.
Поэтому перенаправьте своих пользователей на последнюю страницу, на которой (среди прочего) написано:
Ваша загрузка должна начаться автоматически. Если нет, нажмите [a href="create_csv.php"]here[/a]
.
Что касается инициирования загрузки (например, автоматического вызова create_csv.php) у вас много параметры:
- HTML:
[meta http-equiv="refresh" content="5;url=http://site/create_csv.php"]
- Javascript:
location.href = 'http://site/create_csv.php';
- iframe:
[iframe src="create_csv.php"][/iframe]
Очень легко сделать в том случае, если это действительно необходимо.
Но вам нужно будет немного поработать с JavaScript и файлами cookie:
В PHP вы должны добавить настройку файла cookie
header('Set-Cookie: fileLoading=true');
Затем на странице, где вы вызываете загрузку, вы должны отслеживать с помощью JS (например, один раз в секунду), если есть такой файл cookie (здесь используется плагин jQuery cookie ):
setInterval(function(){
if ($.cookie("fileLoading")) {
// clean the cookie for future downoads
$.removeCookie("fileLoading");
//redirect
location.href = "/newpage";
}
},1000);
Теперь, если файл начинает загружаться, JS распознает его и перенаправляет на нужную страницу после удаления файла cookie.
Конечно, вы можете сказать, что вам нужен браузер, чтобы принимать файлы cookie, JavaScript и так далее, но это работает.
Заголовок, который вы отправляете, является заголовком HTTP. Браузер принимает это как запрос страницы и обрабатывает его как страницу. И в вашем случае это страница, которую необходимо загрузить.
Таким образом, добавление заголовка перенаправления к этому запутывает весь процесс загрузки файла (поскольку заголовки собираются, генерируются в один заголовок и затем отправляются в браузер, вы можете попробовать это, установив несколько заголовков перенаправления IIRC)
Имейте в виду, однако, что автоматическое инициирование загружаемых файлов для пользователей IE вызовет вкладку предупреждения о безопасности. Все три метода, описанные даремоном, показали бы это предупреждение. Вы просто не можете обойти это. Вам будет лучше, если вы предоставите реальные ссылки.
Я нашел один обходной путь для этого, который основан на javascript, поэтому он не совсем безопасен, но для небезопасных критических сайтов он, похоже, работает.
Создайте форму с кнопкой "загрузить", действие которой указывает на сценарий загрузки, затем с помощью javascript поместите что-нибудь в обработчик onsubmit, который удаляет кнопку загрузки и заменяет сообщения на экране. Загрузка все равно должна произойти, и экран изменится. Очевидно, что если есть проблема с загрузите скрипт, тогда все равно будет похоже, что загрузка прошла успешно, даже если он не сработает, но это лучшее, что у меня есть сейчас.
Вы можете попробовать перенаправить на URL-адрес плюс параметр, представляющий содержимое файла. И в перенаправлении вы можете вывести содержимое файла для загрузки.
Это довольно старая проблема, но вот как я добился этого с помощью JS.
// Capture the "click" event of the link.
var link = document.getElementById("the-link");
link.addEventListener("click", function(evt) {
// Stop the link from doing what it would normally do.
evt.preventDefault();
// Open the file download in a new window. (It should just
// show a normal file dialog)
window.open(this.href, "_blank");
// Then redirect the page you are on to whatever page you
// want shown once the download has been triggered.
window.location = "/thank_you.html";
}, true);
Запустите PHP-файл, содержащий загрузку CSV, используя:
<a onclick="popoutWin(\'csvexport.php\')" >Download CSV File</a>
Или
<input name="newThread" type="button" value="Download CSV File"
onclick="popoutWin(\'csvexport.php\')" />
Где функция JavaScript popoutWin
равна
/*
* Popout window that self closes for use with downloads
*/
function popoutWin(link){
var popwin = window.open(link);
window.setTimeout(function(){
popwin.close();
}, 500);
}
Откроется окно, в котором отобразится приглашение на загрузку CSV, а затем сразу же закройте окно, оставив только приглашение.
Вот ответ:
Это работа!
Вам нужны три разные части кода:
HTML
<a id="download_btn" class="btn btn-primary" href="?file=filename&download=1">Download<&/a>
jQuery (запрос)
$('#download_btn').click(function(){
window.location.href = '<?=base_url()?>/?file=<?=$file;?>&download=1';
}).focusout (function(){
window.location.href = '<?=base_url()?>';
return false;
});
PHP
if(isset($_GET['download']) && isset($_GET['file'])){
$zip_path = 'path_to/'.$_GET['file'].'.zip';
if(file_exists($zip_path)){
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($zip_path).'"');
header('Content-Length: ' . filesize($zip_path));
header('Location: '.$zip_path);
}
}
<?php
function force_file_download($filepath, $filename = ''){
if($filename == ''){
$filename = basename($filepath);
}
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . $filename . "\"");
readfile($filepath); // do the double-download-dance (dirty but worky)
}
force_file_download('download.txt');
?>
<script type="text/javascript">
location = 'page2.php'
</script>
Вот решение с использованием javascript.