题
在PHP-基于网站,我想要发一个用户下载包装之后,他们必须填写一个简短的形式。网站发起的下载应当相似的站像download.com,其中说,"你的下载将开始在一个时刻"。
一对夫妇的 可能的方法 我知道约,以及浏览器的兼容性(基于一个快速测试):
1)做 window.open
指向新的文件。
- FireFox 3 blocks this.
- IE6 blocks this.
- IE7 blocks this.
2)建立一个面向新的文件。
- FireFox 3 seems to think this is OK. (Maybe it's because I already accepted it once?)
- IE6 blocks this.
- IE7 blocks this.
How can I do this so that at least these three browsers will not object?
奖励:是否有一个方法,不需要浏览器的有条件的声明?
(我认为download.com 采用这两种方法条件,但我不能让任何一个的工作.)
答复和澄清:
Q: "Why not point the current window to the file?"
A: That might work, but in this particular case, I want to show them some other content while their download starts - for example, "would you like to donate to this project?"
更新:我已经放弃了这种做法。看到我的回答下面的原因。
解决方案
你也可以做一个阶刷新,其中大多数浏览器的支持。Download.com 地方,一个在一个计算机标签。
<meta http-equiv="refresh" content="5;url=/download.php?doc=123.zip"/>
其他提示
更新:我已决定放弃这种做法,而不是只是用户的一个链接到的实际文件。我的推理是这样的:
我的最初尝试在一个服务器启动下载的是阻止通过浏览器。这让我想到:"浏览器是正确的。如何 它的 知道,这是一个合法下载?它的 应该 方框一下这不是很明显的用户发起的。"
任何方法,我可以用于服务器启动可以下载 还 使用通过个人想要发送的恶意软件。因此,下载,只应发生在用户具体要求的文件,通过点击的链接。
你可以不同意,和如果你仍然想要启动下载,希望这个线程将帮助你做到这一点。
我通常只有一个PHP script,其输出的文件直接浏览器与的适当内容的类型
if(file_exists($filename)) {
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: " . $content-type);
header("Content-Disposition: attachment; filename=\"" . basename($filename) . "\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($filename));
readfile("$filename");
}else{
print "ERROR: the file " . basename($filename) . " could not be downloaded because it did not exist.";
}
唯一的缺点是,由于这个集HTTP头,已经可以称之前您有任何其他产出。
但你可以有一个链接到PHP下载的页面,它将导致浏览器弹出一个下载箱没有搞乱的内容。
一个缺点是可能会遇到的问题,即(第6版,在特定的)如果标题都没有设立"正确"。
确保你设置的权利内容的类型,但也考虑设置高速缓冲选项,即(至少) 允许 缓存。如果文件是一个用户可以开放而不是保存(例如MS Word文档)的早期版本的即需要缓存文件,因为它们一方面断的"开放"请求适用的程序,指出该文件的下载在高速缓存。
还有一个相关的问题,如果IE6用户的高速缓存是完全的,不适当地保存文件(因而在适用的应用程序获得的手打开它,它就会抱怨该文件已损坏。
你也可能想要把任何gzip行动上下载过(IE)
IE6/IE7既有的问题与大下载(例如4.x演出...)不是一个可能的情况,因为即甚至没有一个载管理,但东西是知道的。
最后,IE6有时不能很好地处理一下载"推"如果这是开始从内嵌套的框架.我不知道是什么触发的问题,但我发现它是更容易与IE6避免这种情况。
海!
@内森:我决定要做到完全的:有我"getfile.php"载荷的所有必要的东西然后做一个
header("Location: ./$path/$filename");
让浏览器本身,并直接做任何它认为是正确的做用的文件。这甚至适现在歌剧院的我。
但是,这将是一个问题,在环境中,不能直接访问该文件是允许的,在这种情况下,你将不得不寻找不同的方式!(遥感谢我的文件都是公开的Pdf!)
最好的问候,Basty
如何改变位置点的新的文件?(例如通过改变窗口。位置)
我一直只是做了一个框架,它指向的文件。
<iframe src="/download.exe" frameborder="0" height="0" width="0"><a href="/download.exe">Click here to download.</a></iframe>
关于不指向目前的窗口下载。以我的经验你仍然可以显示您"请捐赠"页面,由于下载(只要他们发送正确标题)不实际上更新,浏览器窗口。我这样做是为csv出口对我的一个网站,并尽可能的用户感到关切的是,它只是弹出一个安全的文件窗口。因此,我建议一个简单元重新定向为Soldarnal表明了这一点。
只是总的来说,你有2个目标:
- 开始下载过程
- 显示出用户的一页有一个捐赠的选择
为实现这我会做到以下几点:
当你的用户提交的形式,他得到的结果页上有一个捐赠的选项和一个文本说,他的下载将开始在5秒钟。和头部分的这一页你把元代码作为Soldarnal说:
这就是所有的。
<a href="normaldownload.zip" onclick="use_dhtml_or_ajax_to_display_page()">
目前的页面是不受影响,如果载保存。只是确认下载不在同一个窗口(适当MIME type或 Content-Disposition
)和你就可以显示任何东西。
你可以使用Javascript级的发起下载。这里有一个例子-你可以摆脱的Ajax请求,只是使用目()块。
$("btnDownloadCSV").on('click', function() {
$.ajax({
url: "php_backend/get_download_url",
type: 'post',
contentType: "application/x-www-form-urlencoded",
data: {somedata: "somedata"},
success: function(data) {
// If iFrame already exists, remove it.
if($("[id^='iframeTempCSV_"]).length) {
$("[id^='iframeTempCSV_"]).remove();
}
setTimeout(function() {
// If I'm creating an iframe with the same id, it will permit download only the first time.
// So randHashId appended to ID to trick the browser.
var randHashId = Math.random().toString(36).substr(2);
// Create a fresh iFrame for auto-downloading CSV
$('<iframe id="iframeTempCSV_'+randHashId+'" style="display:none;" src="'+data.filepath+'"></iframe>').appendTo('body');
}, 1000);
},
error: function(xhr, textStatus, errorThrown) {
console.error("Error downloading...");
}
});
});