safari下载文件自动加了html后缀问题


Posted in PHP onNovember 09, 2018

如何下载文件?

方法一、直接通过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如下:

safari下载文件自动加了html后缀问题

可以看到它里面的 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后缀问题

但是我在safari里面的时候,下载下来的文件多了一个 html 后缀,如下图所示

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);

但是看官方手册上面的这段话

safari下载文件自动加了html后缀问题

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

safari下载文件自动加了html后缀问题

正如上面所说,读取大文件的时候,可能会内存耗尽。

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);

看下 官方手册上 的解释

safari下载文件自动加了html后缀问题

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后缀问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
PHP实现分页的一个示例
Oct 09 PHP
php mysql数据库操作类
Jun 04 PHP
连接到txt文本的超链接,不直接打开而是点击后下载的处理方法
Jul 01 PHP
php数组的一些常见操作汇总
Jul 17 PHP
php读取EXCEL文件 php excelreader读取excel文件
Dec 06 PHP
php读取目录及子目录下所有文件名的方法
Oct 20 PHP
php采用curl模仿登录人人网发布动态的方法
Nov 07 PHP
PHP图像处理之使用imagecolorallocate()函数设置颜色例子
Nov 19 PHP
Yii实现单用户博客系统文章详情页插入评论表单的方法
Dec 28 PHP
Yii2下session跨域名共存的解决方案
Feb 04 PHP
微信公众号开发之通过接口删除菜单
Feb 20 PHP
php实现socket推送技术的示例
Dec 20 PHP
centos7上编译安装php7以php-fpm方式连接apache
Nov 08 #PHP
PHP校验15位和18位身份证号的类封装
Nov 07 #PHP
php中如何执行linux命令详解
Nov 06 #PHP
laravel中的一些简单实用功能
Nov 03 #PHP
详解在YII2框架中使用UEditor编辑器发布文章
Nov 02 #PHP
yii2 上传图片的示例代码
Nov 02 #PHP
yii2实现Ueditor百度编辑器的示例代码
Nov 02 #PHP
You might like
什么是短波收听SWL
2021/03/01 无线电
PHP写MySQL数据 实现代码
2009/06/15 PHP
用PHP将网址字符串转换成超链接(网址或email)
2010/05/25 PHP
PHP遍历文件夹与文件类及处理类用法实例
2014/09/23 PHP
smarty模板引擎中内建函数if、elseif和else的使用方法
2015/01/22 PHP
PHP生成可点击刷新的验证码简单示例
2016/05/13 PHP
浅谈PHP中的数据传输CURL
2016/09/06 PHP
老生常谈PHP面向对象之注册表模式
2017/05/26 PHP
PHP token验证生成原理实例分析
2019/06/05 PHP
简单三步,搞掂内存泄漏
2007/03/10 Javascript
CSS常用网站布局实例
2008/04/03 Javascript
jQuery图片轮播的具体实现
2013/09/11 Javascript
兼容Firefox的Javascript XSLT 处理XML文件
2014/12/31 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
jQuery实现的导航下拉菜单效果示例
2016/09/05 Javascript
深入理解vue-router之keep-alive
2017/08/31 Javascript
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
2019/06/07 Javascript
解决layer弹出层的内容页点击按钮跳转到新的页面问题
2019/09/14 Javascript
Python设计模式之命令模式简单示例
2018/01/10 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
Python中pandas dataframe删除一行或一列:drop函数详解
2018/07/03 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
利用anaconda保证64位和32位的python共存
2021/03/09 Python
pygame实现非图片按钮效果
2019/10/29 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
2020/04/01 Python
Python使用pyyaml模块处理yaml数据
2020/04/14 Python
python 实现倒计时功能(gui界面)
2020/11/11 Python
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
巴西购物网站:Submarino
2020/01/19 全球购物
团组织关系介绍信
2014/01/12 职场文书
动漫专业高职生职业生涯规划书
2014/02/15 职场文书
机关干部四风问题自查报告及整改措施
2014/10/26 职场文书
tensorflow+k-means聚类简单实现猫狗图像分类的方法
2021/04/28 Python