PHP 生成文件供下载然后重定向

问题描述 投票:0回答:12

我有一个 PHP 应用程序,它创建一个 CSV 文件,强制使用标头下载该文件。这是代码的相关部分:

header('Content-Type: application/csv'); 
header("Content-length: " . filesize($NewFile)); 
header('Content-Disposition: attachment; filename="' . $FileName . '"'); 
echo $content;
exit(); 

我想做的是在文件构建并发送下载提示后将用户重定向到新页面。只是在末尾添加

header("Location: /newpage")
是行不通的,所以我不知道如何安装它。

php redirect header
12个回答
93
投票

我不认为这是可以做到的——尽管我不是 100% 确定。

常见的情况(例如在流行的下载网站中)是相反的:首先转到after页面,然后开始下载。

因此,将您的用户重定向到final页面(除其他外)显示:

您的下载应该会自动开始。如果没有点击

[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]

15
投票

在确实需要的情况下非常容易做到。

但是您需要在 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等,但它确实有效。


10
投票

您发送的标头是 HTTP 标头。浏览器将其视为页面请求并将其作为页面进行处理。在您的情况下,需要下载一个页面。

因此添加重定向标头会混淆下载文件的整个过程(因为标头是被收集、生成为一个标头然后发送到浏览器的,您可以通过设置多个重定向标头IIRC来尝试这一点)


4
投票

这是一个相当老的问题,但这是我通过 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);

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


3
投票

但是请记住,自动启动 IE 用户的可下载文件将触发安全警告选项卡。 daremon 概述的所有三种方法都会显示此警告。你根本无法回避这个问题。如果您提供真实的链接,您将会得到更好的服务。


3
投票
<?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的解决方案。


2
投票

我找到了一种依赖于 JavaScript 的解决方法,因此它并不完全安全,但对于不安全的关键站点,它似乎有效。

有一个带有标题为“下载”的按钮的表单,其操作设置为指向下载脚本,然后使用 javascript 在 onsubmit 处理程序上放置一些内容,以删除下载按钮并替换屏幕上的消息。下载仍然会发生并且屏幕会发生变化。显然,如果下载脚本存在问题,那么即使没有启动,下载看起来仍然成功,但这是我现在拥有的最好的。


2
投票

更新:新解决方案:

<a id="download-link" 
   href="https://example.com/uploads/myfile.pdf" 
   class="btn">Download</a>

<script>
    jQuery(document).ready(function(  ) {
        jQuery("#download-link").click(function(e) {
            e.preventDefault(); 
            var url = jQuery(this).attr('href');
            var _filename = url.split('/');
            _filename = _filename[_filename.length - 1];
            console.log(_filename);
        
            fetch(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
            })
            .then(response => response.blob())
            .then(response => {
                const blob = new Blob([response], {type: 'application/pdf'});
                const downloadUrl = URL.createObjectURL(blob);
                const a = document.createElement("a");
                a.href = downloadUrl;
                a.download = _filename;
                document.body.appendChild(a);
                a.click();
            });
        
        });
    });
</script>

来源

旧答案:

答案如下:
工作了!
您需要代码的三个不同部分:

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);
            }

        }

1
投票

您可以尝试重定向到 URL 以及代表文件内容的参数。并且在重定向中,您可以输出文件内容以供下载。


1
投票

使用以下命令启动包含 CSV 下载的 PHP 文件:

<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 下载提示,然后立即关闭该窗口,只留下提示。


1
投票

嗯嗯...

将下面的代码放入网站的主要 javascript 中。

 if (window.location.pathname == '/url_of_redirect/') {
        window.open(location.protocol + '//' + location.hostname + '/url_of_download.zip', '_parent');
    }

解释: 它使用 php 进行正常的重定向到您将定义的某个 url,在 javascipt 中它表示:如果路径名与重定向的路径相同“/url_of_redirect/”,那么它将在新页面上打开该 url,生成下载。


0
投票

此解决方案使用 php 会话,并且不会出现任何弹出窗口阻止程序的问题:

index.php

<?php
session_start();

if (!empty($_SESSION['download'])) {
    echo '<p>Download in progress...</p>'.PHP_EOL;

    // https://stackoverflow.com/questions/12539011/header-location-in-new-tab/12539054#comment16884210_12539054
    echo '<script>
setTimeout(() => {
    window.location.href = "'.$_SESSION['download'].'";
}, 3000);                          
</script>'.PHP_EOL;

    unset($_SESSION['download']);
}
?>
<a href="download.php">download</a>

下载.php

<?php
session_start();

// create file.zip

$_SESSION['download'] = 'file.zip';

// https://stackoverflow.com/a/11804706/3929620
header('Refresh: 0; Url=index.php');
exit;
© www.soinside.com 2019 - 2024. All rights reserved.