Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 启动下载的最佳方式?_Php_Javascript_Download - Fatal编程技术网

Php 启动下载的最佳方式?

Php 启动下载的最佳方式?,php,javascript,download,Php,Javascript,Download,在一个基于PHP的网站上,我想在用户填写完一个简短的表单后向他们发送一个下载包。网站发起的下载应该类似于download.com这样的网站,上面写着“你的下载马上就要开始了。” 一些可能的方法我知道,以及浏览器兼容性(基于快速测试): 1)打开一个窗口。打开指向新文件的。 - FireFox 3 blocks this. - IE6 blocks this. - IE7 blocks this. - FireFox 3 seems to think this is OK. (May

在一个基于PHP的网站上,我想在用户填写完一个简短的表单后向他们发送一个下载包。网站发起的下载应该类似于download.com这样的网站,上面写着“你的下载马上就要开始了。”

一些可能的方法我知道,以及浏览器兼容性(基于快速测试):

1)打开一个
窗口。打开指向新文件的

- FireFox 3 blocks this.  
 - IE6 blocks this.  
 - IE7 blocks this.
- 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? 
2)创建指向新文件的iframe。

- FireFox 3 blocks this.  
 - IE6 blocks this.  
 - IE7 blocks this.
- 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?"

更新:我已经放弃了这种方法。请参阅下面我的答案以了解原因。

如何更改位置以指向新文件?(例如,通过更改window.location)

我通常只有一个PHP脚本,可以将文件以适当的内容类型直接输出到浏览器

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下载页面的链接,它会导致浏览器弹出一个下载框,而不会弄乱当前页面的内容。

你也可以进行元刷新,这是大多数浏览器都支持的。Download.com将一个放置在noscript标记中

<meta http-equiv="refresh" content="5;url=/download.php?doc=123.zip"/>

我总是制作一个指向文件的iframe

<iframe src="/download.exe" frameborder="0" height="0" width="0"><a href="/download.exe">Click here to download.</a></iframe>

关于不将当前窗口指向下载。 根据我的经验,您仍然可以显示“请捐赠”页面,因为下载(只要它们发送正确的标题)实际上不会更新浏览器窗口。 我在我的一个网站上进行csv导出,就用户而言,它只会弹出一个安全的文件窗口。
因此,我推荐一个简单的元重定向,如索尔达纳尔所示。

总结一下,您有两个目标:

  • 开始下载过程
  • 向用户显示带有“捐赠”选项的页面
  • 为此,我将采取以下措施:

    当您的用户提交表单时,他会得到一个带有捐赠选项的页面,并显示一条文本,说明他的下载将在5秒钟后开始。在这一页的开头部分,你把元代码放在Soldarnal说的地方:
    一个问题是,如果标题设置不“正确”,您可能会遇到IE(特别是版本6)的问题

    确保设置正确的内容类型,但也可以考虑为IE设置缓存选项(至少)以允许缓存。如果文件是用户可以打开而不是保存的文件(例如MS Word文档),IE的早期版本需要缓存该文件,因为他们将“打开”请求交给适用的应用程序,指向缓存中下载的文件

    还有一个相关的问题,如果IE6用户的缓存已满,它将无法正确保存文件(因此,当适用的应用程序获得打开它的许可时,它将抱怨文件已损坏)

    您可能还想在下载中打开任何gzip操作(对于IE)

    IE6/IE7都有大量下载的问题(例如4.x Gigs…),这不太可能发生,因为IE甚至没有下载管理器,但需要注意一些事情


    最后,IE6有时不能很好地处理下载“推送”如果它是从嵌套的iframe中启动的。我不确定是什么触发了该问题,但我发现使用IE6可以更容易地避免这种情况。

    更新:我决定放弃这种方法,而只是向用户提供一个指向实际文件的链接。我的理由如下:

    我最初尝试的服务器启动下载被浏览器阻止。这让我想到:“浏览器是对的。它如何知道这是合法下载?它应该阻止一个显然不是用户启动的下载。”

    我可以用于服务器启动下载的任何方法也可能被想要发送恶意软件的人使用。因此,只有当用户通过单击链接明确请求该文件时,才能进行下载

    你可以自由地提出不同意见,如果你仍然想开始下载,希望此线程能帮助你完成下载。

    Hoi

    @内森: 我决定这样做:让我的“getfile.php”加载所有必要的内容,然后执行

    header("Location: ./$path/$filename");
    
    让浏览器自己直接对文件执行它认为正确的操作。这在我的Opera中甚至可以很好地工作

    但在不允许直接访问文件的环境中,这将是一个问题,在这种情况下,您必须找到不同的方法!(感谢Discordia,我的文件是公共PDF!)


    向您致意,Basty

    您可以使用Javascript/jQuery启动下载

    <a href="normaldownload.zip" onclick="use_dhtml_or_ajax_to_display_page()">
    
    $(“btndownloadcv”)。在('click',function()上{
    $.ajax({
    url:“php_后端/get_下载_url”,
    键入:“post”,
    contentType:“application/x-www-form-urlencoded”,
    数据:{somedata:“somedata”},
    成功:功能(数据){
    //如果iFrame已经存在,请将其删除。
    如果($(“[id^='iframetempcv_“]).length){
    $(“[id^='iframeTempCSV_u3;]).remove();
    }
    setTimeout(函数(){
    //如果我正在创建一个具有相同id的iframe,它将只允许第一次下载。
    //所以randHashId附加到ID以欺骗浏览器。
    var randHashId=Math.random().toString(36).substr(2);
    //创建用于自动下载CSV的新iFrame
    $('')。附于('正文');
    }, 1000);
    },
    错误:函数(xhr、textStatus、errorshown){
    控制台错误(“下载错误…”);
    }