假设我有一个网站的下载链接。
当这些链接被点击时,它们会发送一个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',并将路径作为get参数传递。
需要注意的是,这个解决方案的PHP部分只是一个简单的演示,可能非常不安全。它允许用户下载任何文件,而不仅仅是预定义的文件集。这意味着他们可以下载网站本身的源代码的一部分,可能包含API凭据等重要信息。
只需在你的 JavaScript 中调用 window.location.href = new_url
,浏览器就会重定向到该 URL,就像用户在地址栏中键入该 URL 一样。
阅读答案 - 包括被接受的答案,我想指出通过GET直接传递路径给readfile的安全隐患。
对于一些人来说这可能很显然,但有些人可能只是复制/粘贴此代码:
<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET['path']);
readfile($_GET['path']);
?>
如果我将像“/path/to/fileWithSecrets”这样的内容传递给该脚本,会发生什么情况? 给定的脚本将愉快地发送任何Web服务器用户可以访问的文件。
有关如何防止此问题,请参考此讨论:如何确保文件路径在特定子目录内?
Content-disposition: attachment; filename=fname.ext
这将强制任何浏览器下载文件而不在浏览器窗口中呈现它。
<Files *.apk>
ForceType application/force-download
Header set Content-Disposition attachment
Header set Content-Type application/vnd.android.package-archive
Header set Content-Transfer-Encoding binary
</Files>
我建议在页面上添加一个不可见的iframe,并将其src设置为从服务器收到的url - 下载将在不重新加载页面的情况下开始。
或者,您可以将当前的document.location.href设置为接收到的网址。但是,如果请求的文档实际上不存在,这可能会导致用户看到错误。
针对顶部答案,我有一个可能的解决方案来应对安全风险。
<?php
if(isset($_GET['path'])){
if(in_array($_GET['path'], glob("*/*.*"))){
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET['path']);
readfile($_GET['path']);
}
}
?>
<iframe id="download" style="display:none"></iframe>
并且
<input type="submit" value="Download" onclick="ChangeSource('document_path');return false;">
JavaScript:
<script type="text/javascript">
<!--
function ChangeSource(path){
document.getElementByID('download').src = 'path_to_php?path=' + document_path;
}
-->
</script>
if (!file_exists($path)) { header("HTTP/1.1 404 Not Found"); exit; }
可以解决问题。该代码会检查文件是否存在,如果不存在,则会发送一个“404未找到”错误消息并退出程序。 - S B