假设我在我的网站上有文件的下载链接。
单击这些链接时,会向服务器发送 AJAX 请求,服务器会返回带有文件位置的 URL。
我想要做的是在响应返回时指示浏览器下载文件。有没有便携的方法来做到这一点?
假设我在我的网站上有文件的下载链接。
单击这些链接时,会向服务器发送 AJAX 请求,服务器会返回带有文件位置的 URL。
我想要做的是在响应返回时指示浏览器下载文件。有没有便携的方法来做到这一点?
我们这样做:首先添加这个脚本。
<script type="text/javascript">
function populateIframe(id,path)
{
var ifrm = document.getElementById(id);
ifrm.src = "download.php?path="+path;
}
</script>
把它放在你想要下载按钮的地方(这里我们只使用一个链接):
<iframe id="frame1" style="display:none"></iframe>
<a href="javascript:populateIframe('frame1','<?php echo $path; ?>')">download</a>
文件“download.php”(需要放在您的服务器上)仅包含:
<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET['path']);
readfile($_GET['path']);
?>
因此,当您单击该链接时,隐藏的 iframe 将获取/打开源文件“download.php”。以路径作为获取参数。我们认为这是最好的解决方案!
应该注意的是,该解决方案的 PHP 部分是一个简单的演示,并且可能非常非常不安全。它允许用户下载任何文件,而不仅仅是预定义的文件集。这意味着他们可以下载站点本身的部分源代码,可能包含 API 凭据等。
我创建了一个开源jQuery 文件下载插件(带有示例的演示)(GitHub),它也可以帮助您解决问题。它与 iframe 的工作方式非常相似,但有一些很酷的功能,我发现这些功能非常方便:
只需window.location.href = new_url
从您的 javascript调用,它就会将浏览器重定向到该 URL,因为它是用户在地址栏中键入的
阅读答案 - 包括已接受的答案,我想指出通过 GET 将路径直接传递给 readfile 的安全隐患。
对某些人来说这似乎很明显,但有些人可能只是复制/粘贴此代码:
<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET['path']);
readfile($_GET['path']);
?>
那么如果我将诸如“/path/to/fileWithSecrets”之类的东西传递给这个脚本会发生什么?给定的脚本会很高兴地发送 webserver-user 可以访问的任何文件。
有关如何防止这种情况的信息,请参阅此讨论:如何确保文件路径在给定的子目录中?
如果这是您自己的服务器应用程序,那么我建议使用以下标头
Content-disposition: attachment; filename=fname.ext
这将强制任何浏览器下载文件,而不是在浏览器窗口中呈现它。