我的服务器上有一个CSV文件。如果用户点击了应该下载的链接,而是在浏览器窗口中打开它。
我的代码如下
<a href="files/csv/example/example.csv">
Click here to download an example of the "CSV" file
</a>
这是一个普通的网络服务器,我可以完成所有的开发工作。
我尝试过类似的事情:
<a href="files/csv/example/csv.php">
Click here to download an example of the "CSV" file
</a>
现在我的csv.php
文件的内容:
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
现在我的问题是它正在下载,但不是我的CSV文件。它会创建一个新文件。
答案 0 :(得分:103)
要强制下载服务器上的所有CSV文件,请添加.htaccess文件:
AddType application/octet-stream csv
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
readfile("/path/to/yourfile.csv");
答案 1 :(得分:22)
或者您可以使用HTML5执行此操作。只需
<a href="example.csv" download>download not open it</a>
答案 2 :(得分:15)
这是不可靠的,因为由浏览器决定如何处理要求检索的URL。
您可以通过发送Content-disposition标头建议向浏览器提供“保存到磁盘”:
header("Content-disposition: attachment");
我不确定各种浏览器是否支持这种情况。另一种方法是发送一个Content-type的application / octet-stream,但这是一个hack(你基本上是告诉浏览器“我不是在告诉你这是什么类型的文件”而且取决于大多数事实然后,浏览器将提供下载对话框)并据称导致Internet Explorer出现问题。
中详细了解相关信息 编辑您已经切换到PHP文件来传递数据 - 这是设置Content-disposition标头所必需的(除非有一些神秘的Apache设置也可以执行此操作)。现在剩下要做的就是让PHP文件读取CSV文件的内容并打印出来 - 标题中的filename=example.csv
只向客户端浏览器建议用于文件的名称,实际上并不是从服务器上的文件中获取数据。
答案 3 :(得分:12)
这是一个更加浏览器安全的解决方案:
$fp = @fopen($yourfile, 'rb');
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="yourname.file"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".filesize($yourfile));
}
else
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="yourname.file"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".filesize($yourfile));
}
fpassthru($fp);
fclose($fp);
答案 4 :(得分:7)
配置服务器以使用媒体类型application/octet-stream
发送文件。
答案 5 :(得分:3)
干净利落的解决方案:
<?php
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="example.csv"');
header("Content-Length: " . filesize("example.csv"));
$fp = fopen("example.csv", "r");
fpassthru($fp);
fclose($fp);
?>
答案 6 :(得分:2)
这意味着您的浏览器可以处理此文件类型。
如果您不喜欢它,最简单的方法是提供ZIP文件。每个人都可以处理ZIP文件,默认情况下可以下载。
答案 7 :(得分:1)
此页面上的上一个答案介绍了如何使用.htaccess强制下载某种类型的所有文件。但是,该解决方案不适用于所有浏览器中的所有文件类型。这是一种更可靠的方式:
<FilesMatch "\.(?i:csv)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
您可能需要刷新浏览器缓存才能看到此工作正常。
答案 8 :(得分:1)
如果您正在使用您的应用程序本身...我希望此代码有所帮助。
在href中 - 您必须将download_file.php与您的网址一起添加:
<a class="download" href="'/download_file.php?fileSource='+http://www.google.com/logo_small.png" target="_blank" title="YourTitle">
/* Here is the Download.php file to force download stuff */
<?php
$fullPath = $_GET['fileSource'];
if($fullPath) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Disposition: attachment; filename=\"" . $path_parts["basename"]."\""); // Use 'attachment' to force a download
header("Content-type: application/pdf"); // Add here more headers for diff. extensions
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
}
if($fsize) { // Checking if file size exist
header("Content-length: $fsize");
}
readfile($fullPath);
exit;
}
?>
答案 9 :(得分:0)
要强制下载,您可以使用Content-Type: application/force-download
标头,大多数浏览器都支持该标头:
function downloadFile($filePath)
{
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
}
更好的方式
以这种方式下载文件并不是最佳方法,特别是对于大文件。 PHP将需要额外的CPU /内存来读取和输出文件内容,处理大文件时可能会达到时间/内存限制。
更好的方法是使用PHP进行身份验证并授予对文件的访问权限,并且应使用X-SENDFILE方法将实际的文件服务委托给Web服务器(需要某些Web服务器配置):
X-SENDFILE
本身受Lighttpd支持:https://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-file mod_xsendfile
模块:https://tn123.org/mod_xsendfile/在Ubuntu上可以通过以下方式安装:apt install libapache2-mod-xsendfile
X-Accel-Redirect
标头:https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/ 在将Web服务器配置为处理X-SENDFILE
之后,只需将readfile($filePath)
替换为header('X-SENDFILE: ' . $filePath)
,Web服务器将负责文件服务,这将比使用PHP {{1} }。
(对于Nginx,请使用readfile
标头代替X-Accel-Redirect
)
注意:如果最终下载空文件,则意味着您没有配置Web服务器来处理X-SENDFILE
标头。检查上面的链接,了解如何正确配置您的Web服务器。