我有一个 PHP 应用程序,它创建一个 CSV 文件,强制使用标头下载该文件。这是代码的相关部分:
header('Content-Type: application/csv');
header("Content-length: " . filesize($NewFile));
header('Content-Disposition: attachment; filename="' . $FileName . '"');
echo $content;
exit();
我想做的是在文件构建并发送下载提示后将用户重定向到新页面。只是在末尾添加
header("Location: /newpage")
是行不通的,所以我不知道如何安装它。
我不认为这是可以做到的——尽管我不是 100% 确定。
常见的情况(例如在流行的下载网站中)是相反的:首先转到after页面,然后开始下载。
因此,将您的用户重定向到final页面(除其他外)显示:
您的下载应该会自动开始。如果没有点击
[a href="create_csv.php"]here[/a]
。
关于启动下载(例如自动调用create_csv.php),您有很多选择:
[meta http-equiv="refresh" content="5;url=http://site/create_csv.php"]
location.href = 'http://site/create_csv.php';
[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来尝试这一点)
这是一个相当老的问题,但这是我通过 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);
但是请记住,自动启动 IE 用户的可下载文件将触发安全警告选项卡。 daremon 概述的所有三种方法都会显示此警告。你根本无法回避这个问题。如果您提供真实的链接,您将会得到更好的服务。
<?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的解决方案。
我找到了一种依赖于 JavaScript 的解决方法,因此它并不完全安全,但对于不安全的关键站点,它似乎有效。
有一个带有标题为“下载”的按钮的表单,其操作设置为指向下载脚本,然后使用 javascript 在 onsubmit 处理程序上放置一些内容,以删除下载按钮并替换屏幕上的消息。下载仍然会发生并且屏幕会发生变化。显然,如果下载脚本存在问题,那么即使没有启动,下载看起来仍然成功,但这是我现在拥有的最好的。
更新:新解决方案:
<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>
$('#download_btn').click(function(){
window.location.href = '<?=base_url()?>/?file=<?=$file;?>&download=1';
}).focusout (function(){
window.location.href = '<?=base_url()?>';
return false;
});
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);
}
}
您可以尝试重定向到 URL 以及代表文件内容的参数。并且在重定向中,您可以输出文件内容以供下载。
使用以下命令启动包含 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 下载提示,然后立即关闭该窗口,只留下提示。
嗯嗯...
将下面的代码放入网站的主要 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,生成下载。
此解决方案使用 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;