内容简介:如果文件是保存在服务器上面的,可以直接用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++整数常量的前缀和后缀
- 常用算法思想之动态规划的后缀思想
- 浅谈后缀自动机:概述,构建与简单应用
- 【技术分享】劫持一个国家的顶级域名之旅-域名后缀的隐藏威胁(下)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Responsive Web Design
Ethan Marcotte / Happy Cog / 2011-6 / USD 18.00
From mobile browsers to netbooks and tablets, users are visiting your sites from an increasing array of devices and browsers. Are your designs ready? Learn how to think beyond the desktop and craft be......一起来看看 《Responsive Web Design》 这本书的介绍吧!