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 58

10 ответов:

Я не думаю, что это можно сделать - хотя я не уверен на 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 и cookies:

в 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.

конечно, вы можете сказать, что вам нужен браузер, чтобы принимать куки, 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);

Via - https://www.daniweb.com/web-development/php/threads/463652/page-not-redirecting-after-sending-headers-in-php

запустите 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.