用JavaScript开始下载文件

Vas*_*sil 54 javascript ajax download

假设我有我网站上文件的下载链接.

单击这些链接时,会向服务器发送一个AJAX请求,该请求返回带有文件位置的URL.

我想要做的是在响应回来时指示浏览器下载文件.有可行的方法吗?

小智 24

我们这样做:首先添加此脚本.

<script type="text/javascript">
function populateIframe(id,path) 
{
    var ifrm = document.getElementById(id);
    ifrm.src = "download.php?path="+path;
}
</script>
Run Code Online (Sandbox Code Playgroud)

把它放在你想要下载按钮的地方(这里我们只使用一个链接):

<iframe id="frame1" style="display:none"></iframe>
<a href="javascript:populateIframe('frame1','<?php echo $path; ?>')">download</a>
Run Code Online (Sandbox Code Playgroud)

文件'download.php'(需要放在你的服务器上)只包含:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>
Run Code Online (Sandbox Code Playgroud)

因此,当您单击该链接时,隐藏的iframe将获取/打开源文件'download.php'.使用path作为get参数.我们认为这是最好的解决方案!

应该注意的是,这个解决方案的PHP部分是一个简单的演示,可能非常非常不安全.它允许用户下载任何文件,而不仅仅是预定义的集合.这意味着他们可以下载网站本身的部分源代码,可能包含API凭据等.

  • 什么阻止用户查看源代码,获取download.php的URL,然后浏览到http://www.yoursite.com/download.php?path=config.php尝试获取密码?换句话说:请*请*不要这样做. (50认同)
  • @Fabio:`if(!file_exists($ path)){header("HTTP/1.1 404 Not Found"); 出口; 应该做的伎俩 (6认同)
  • 跟进@Grim ...的评论,他绝对是正确的,不要这样做.将iframe src链接直接指向该文件,并使用.htaccess设置该特定文件类型的标头信息. (5认同)
  • 不错但是......你怎么用这种方式处理404错误? (2认同)

Joh*_*ner 18

我已经创建了一个开源的jQuery文件下载插件(带示例的演示)(GitHub),它也可以帮助你的情况.它与iframe的工作方式非常相似,但有一些我发现非常方便的很酷的功能:

  • 用户永远不会离开他们发起文件下载的同一页面.此功能对于现代Web应用程序变得至关重要
  • 经过测试的跨浏览器支持(包括移动!)
  • 它以类似于jQuery的AJAX API的方式支持POST和GET请求
  • successCallback和failCallback函数允许您明确用户在任一情况下看到的内容
  • 结合jQuery UI,开发人员可以轻松地显示一个模式告诉用户文件下载正在发生,在下载开始后解除模式,甚至以友好的方式通知用户发生了错误.有关此示例,请参阅演示.


Dan*_*han 14

阅读答案 - 包括已接受的答案我想指出通过GET直接将路径传递给readfile的安全隐患.

对某些人来说似乎很明显,但有些人可能只是复制/粘贴此代码:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>
Run Code Online (Sandbox Code Playgroud)

那么如果我将'/ path/to/fileWithSecrets'之类的内容传递给此脚本会发生什么?给定的脚本将很乐意发送webserver-user有权访问的任何文件.

有关如何防止这种情况的信息,请参阅此讨论:如何确保文件路径在给定的子目录中?


fas*_*ana 10

如果这是您自己的服务器应用程序,那么我建议使用以下标头

Content-disposition: attachment; filename=fname.ext
Run Code Online (Sandbox Code Playgroud)

这将强制任何浏览器下载文件,而不是在浏览器窗口中呈现它.


Gar*_*eth 7

只需window.location.href = new_url从您的javascript 调用它,它将浏览器重定向到该URL,因为用户已将其键入到地址栏中


小智 5

试试这个库https://github.com/PixelsCommander/Download-File-JS 它比之前描述的所有解决方案都更现代,因为使用“下载”属性和方法组合来带来最佳体验。

在这里解释 - http://pixelscommander.com/en/javascript/javascript-file-downliading-ignore-content-type/

似乎是开始在 JavaScript 中下载的理想代码。