内容简介:如果文件是保存在服务器上面的,可以直接用nginx下载文件比如说可以供用户下载pdf文件,那么我的nginx配置可以是这样子的:按照上面的配置,当我请求
如何下载文件?
方法一、直接通过nginx下载静态文件
如果文件是保存在服务器上面的,可以直接用nginx下载文件
比如说可以供用户下载pdf文件,那么我的nginx配置可以是这样子的:
location ~ /document/(.*)\.pdf$ { root /home/nemo/myfile; try_files /$uri 404; }
按照上面的配置,当我请求 http://fbd.intelleeegooo.cc/document/test.pdf
的时候,我服务器上的位于 /home/nemo/myfile/document/test.pdf
的这个文件就被下载了。当找不到相应的文件的时候,就会返回 404
。
方法二、通过 php 读取文件并下载
但上面这种方式是所有人都可以下载pdf文件的,假如说下载文件这个动作是与账号有关的,比如说某用户只能下载某些文件,那么就需要在php里面对用户账户进行处理并且下载相关文件。
看我在index.php里面这段示例代码,这段代码的功能下载test.txt文件
<?php $filePath = '/home/nemo/fun/testdownloadfile/test.txt'; $fileName = 'test.txt'; readfile($filePath);
比如说我开了一个8764端口,nginx配置如下:
server { listen 8764; server_name xx.xx.xx; …… …… …… location / { root /home/nemo/fun/testdownloadfile; fastcgi_pass 127.0.0.1:xxxx; fastcgi_index index.php; include fastcgi.conf; } }
配置文件里面的 fastcgi_pass
后面可以是ip+端口,也可以是unix_socket的路径。具体根据你安装的php的里面的 php-fpm.conf
的 listen
来决定。
我们用 command + option + i
快捷键打开浏览器的调试模式,当我在浏览器里面请求 http://xx.xx.xx:8764/
的时候,结果是浏览器直接把txt文件的内容显示在了页面上。
看一下调试模式里面的这个请求,它的response header如下:
可以看到它里面的 Content-Type
是 text/html
,表示是一个html文件,所以浏览器就直接展示在页面上了。【关于常用的一些 Content-Type
,可以见本文最后】
那么我改一下代码,在里面设置一下header,示例代码如下:
<?php $filePath = '/home/nemo/fun/testdownloadfile/test.txt'; $fileName = 'test.txt'; header('Content-Disposition: attachment; filename=' . $fileName); readfile($filePath);
我在chrome里面新建一个tab页输入url http://fbd.intelleeegooo.cc/document/test.pdf
的时候,成功下载了这个文件,如下图所示:
但是我在safari里面的时候,下载下来的文件多了一个 html
后缀,如下图所示
我再改下代码,设置 Content-Type
,看如下示例代码:
<?php $filePath = '/home/nemo/fun/testdownloadfile/test.txt'; $fileName = 'test.txt'; header('Content-Type: application/octet-stream;charset=utf-8'); header('Content-Disposition: attachment; filename=' . $fileName); readfile($filePath);
这样改过之后,在safari里面下载的文件就是正常的了,不带html后缀的。
2.2 在php里面读取并输出文件的几种方法
在设置完header信息之后,下面几种方法都可以用来输出文件
-
-
file_get_contents()
,这个方法是把文件的内容以字符串的形式全部读取到内存里面。当文件比较大的时候,会超过内存限制
-
$content = file_get_contents($filePath); echo $content;
-
-
file()
,将文件以行的形式全部读取到数组中。当文件比较大的时候,会超过内存限制
-
$f = file($filePath); while(list($line, $content) = each($f)) { // $line是int类型表示是第几行(从0开始), $content是字符串类型表示这一行的内容 echo $content; }
-
-
readfile()
,读取文件并且写入到输出缓冲区。这种方式可以输出大文件,读取单个文件不会超出内存限制。
-
ob_end_clean(); readfile($filePath);
但是看 官方手册上面的这段话
readfile自身不会导致任何内存问题。如果出现内存不足的问题,使用 ob_get_level()
确保输出缓存已经关闭。
但 readfile()
方法还是可以会引起内存耗尽,鸟哥的 这篇笔记里面 写到:
readfile实际上还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出。
-
-
fopen()
,这就类似于 C语言 里面的读取文件。fopen每次可以指定读取某个块大小的内容,可以读入大文件。不会超过内存限制
-
$file = @fopen($filePath,"rb"); while(!feof($file)) { print(@fread($file, 1024*8)); ob_flush(); flush(); }
2.3 内存限制
在php的配置文件 php.ini
里面,有一个 memory_limit
这个设置项,设置的是每个脚本可以分配的内存。
如下图所示,我自己放宽了一点变成了256M,默认是128M
正如上面所说,读取大文件的时候,可能会内存耗尽。
php里面有 ini_set()
方法可以在脚本运行时保持新的值,在脚本结束时恢复。
并不是 php.ini
里面的所有设置项都可以被修改,所有可以被 ini_set()
修改的选项可以从 官方手册里面的这个清单 知晓
有一种方法可以在执行的时候动态的修改脚本可以使用的内存大小,而不一定非要修改php.ini文件,毕竟php.ini是针对全局的。
在脚本里面动态的修改一些设置,只对该脚本有效,实际上并不真正地修改 php.ini
文件。
2.5 时间限制
一般情况下,使用php下载文件的时候,会加上一行 set_time_limit(0);
,表示不限制这个php脚本执行的时间
<?php $filePath = '/home/nemo/fun/testdownloadfile/test.txt'; $fileName = 'test.txt'; set_time_limit(0); header('Content-Type: application/octet-stream;charset=utf-8'); header('Content-Disposition: attachment; filename=' . $fileName); readfile($filePath);
看下 官方手册上 的解释
Content-Disposition
相关解释
在常规的HTTP应答中, Content-Disposition
消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地
Content-Disposition
消息头最初是在MIME标准中定义的,HTTP表单及POST 请求只用到了其所有参数的一个子集。只有form-data以及可选的name和filename三个参数可以应用在HTTP场景中
inline
- inline展示txt文件
看如下示例代码,设置inline内联,将上面的test.txt文件在浏览器里面展示
<?php $filePath = '/home/nemo/fun/testdownloadfile/test.txt'; $fileName = 'test.txt'; header('Content-Disposition: inline; filename=' . $fileName); readfile($filePath);
常用的几种 Content-Type
类型
下面列一下常用的几种Content-Type
-
text/html
,内容是html格式 -
text/plain
,内容是纯文本格式 -
image/gif
, gif图片格式 -
image/jpeg
, jpg图片格式 -
image/png
, png图片格式 -
multipart/form-data
,常见的 POST 数据提交的方式。当需要上传文件时,会用到这种类型 -
application/json
,消息主体是序列化后的 JSON 字符串 -
application/octet-stream
,二进制流数据。一般在下载文件的时候比较常见 -
application/x-www-form-urlencoded
, 浏览器的原生form表单,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key和val都进行了URL转码
以上所述就是小编给大家介绍的《safari下载文件自动加了html后缀》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- .*4444后缀勒索病毒数据库文件修复
- SA 后缀数组入门 — Luogu P3809 【模板】后缀排序
- C++整数常量的前缀和后缀
- 常用算法思想之动态规划的后缀思想
- 浅谈后缀自动机:概述,构建与简单应用
- 【技术分享】劫持一个国家的顶级域名之旅-域名后缀的隐藏威胁(下)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
我用微软改变世界
保罗·艾伦 / 吴果锦 / 浙江人民出版社 / 2012-3 / 46.00元
《我用微软改变世界(微软联合创始人保罗•艾伦回忆录)》内容简介:1975年,两个从大学退学的男孩夜以继日地设计一款软件。其中一个男孩就是后来的世界首富比尔盖茨,而另外一个则作为盖茨背后的男人,一直生活在盖茨的阴影里,其实,他的人生经历远比盖茨更为传奇和丰富。 16岁,与比尔盖茨在顶级名校湖畔中学相遇,成为最佳拍档,无数趣事,无数闹腾,高呼“处男万岁”还不够,还得意扬扬把这话刻在碑上留给学弟们......一起来看看 《我用微软改变世界》 这本书的介绍吧!