解析如何在PHP下载文件名中解决乱码的问题


Posted in PHP onJune 20, 2013

通过把Content-Type设置为application/octet-stream,可以把动态生成的内容当作文件来下载,相信这个大家都会。那么用Content-Disposition设置下载的文件名,这个也有不少人知道吧。基本上,下载程序都是这么写的:

$filename = "document.txt";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
print "Hello!";
?>

但是,如果$filename是UTF-8编码的,有些浏览器就无法正常处理了。比如把上面那个程序稍稍改一下:
$filename = "中文 文件名.txt";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
print "Hello!";
?>

输出的header实际上是这样子:
Content-Disposition: attachment; filename=中文 文件名.txt其实按照RFC2231的定义,多语言编码的Content-Disposition应该这么定义:
Content-Disposition: attachment; filename*="utf8''%E4%B8%AD%E6%96%87%20%E6%96%87%E4%BB%B6%E5%90%8D.txt"即:
•filename后面的等号之前要加 *
•filename的值用单引号分成三段,分别是字符集(utf8)、语言(空)和urlencode过的文件名。
•最好加上双引号,否则文件名中空格后面的部分在Firefox中显示不出来
•注意urlencode的结果与php的urlencode函数结果不太相同,php的urlencode会把空格替换成+,而这里需要替换成%20
经过试验,发现几种主流浏览器的支持情况如下:
IE6
attachment; filename=""
FF3
attachment; filename="UTF-8文件名"
attachment; filename*="utf8''"
O9
attachment; filename="UTF-8文件名"
Safari3(Win)
貌似不支持?上述方法都不行
这样看来,程序必须得这样写才能支持所有主流浏览器:
$ua = $_SERVER["HTTP_USER_AGENT"];
$filename = "中文 文件名.txt";
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
header('Content-Type: application/octet-stream');
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8/'/'' . $filename . '"');
} else {
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
print 'ABC';
?>
PHP 相关文章推荐
PHP实现图片简单上传
Oct 09 PHP
第六节--访问属性和方法
Nov 16 PHP
php 3行代码的分页算法(求起始页和结束页)
Oct 21 PHP
PHP FTP操作类代码( 上传、拷贝、移动、删除文件/创建目录)
May 10 PHP
php实现获取文件mime类型的方法
Feb 11 PHP
关于WordPress的SEO优化相关的一些PHP页面脚本技巧
Dec 10 PHP
PHP编写简单的App接口
Aug 28 PHP
PHP针对伪静态的注入总结【附asp与Python相关代码】
Aug 01 PHP
PHP goto语句用法实例
Aug 06 PHP
php设计模式之观察者模式定义与用法经典示例
Sep 19 PHP
PHP反射原理与用法深入分析
Sep 28 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
Feb 27 PHP
解析smarty 截取字符串函数 truncate的用法介绍
Jun 20 #PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
Jun 20 #PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
Jun 20 #PHP
解析php利用正则表达式解决采集内容排版的问题
Jun 20 #PHP
解析使用substr截取UTF-8中文字符串出现乱码的问题
Jun 20 #PHP
用Json实现PHP与JavaScript间数据交换的方法详解
Jun 20 #PHP
使用php 获取时间今天明天昨天时间戳的详解
Jun 20 #PHP
You might like
php不用正则验证真假身份证
2013/11/06 PHP
php之curl设置超时实例
2014/11/03 PHP
php pdo oracle中文乱码的快速解决方法
2016/05/16 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
2019/10/20 PHP
Mootools 1.2教程 事件处理
2009/09/15 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
2012/10/11 Javascript
原生javascript和jquery判断浏览器版本等信息
2013/07/04 Javascript
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
javascript 获取iframe里页面中元素值的方法
2014/02/17 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
微信小程序 Toast自定义实例详解
2017/01/20 Javascript
使用ionic播放轮询广告的实现方法(必看)
2017/04/24 Javascript
AngularJS的ng-click传参的方法
2017/06/19 Javascript
vue深入解析之render function code详解
2017/07/18 Javascript
微信小程序 页面跳转传值实现代码
2017/07/27 Javascript
Vue自定义事件(详解)
2017/08/19 Javascript
用最简单的方法判断JavaScript中this的指向(推荐)
2017/09/04 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
2020/05/20 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
Python 限制线程的最大数量的方法(Semaphore)
2019/02/22 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
基于Python实现拆分和合并GIF动态图
2019/10/22 Python
Python3 xml.etree.ElementTree支持的XPath语法详解
2020/03/06 Python
使用Python对Dicom文件进行读取与写入的实现
2020/04/20 Python
Python爬虫代理池搭建的方法步骤
2020/09/28 Python
CSS3 flex布局之快速实现BorderLayout布局
2015/12/03 HTML / CSS
HTML5去掉输入框type为number时的上下箭头的实现方法
2020/01/03 HTML / CSS
viagogo英国票务平台:演唱会、体育比赛、戏剧门票
2017/03/24 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
公司合作协议书范本
2014/04/18 职场文书
初中同学会活动方案
2014/08/22 职场文书
2015年初中教务处工作总结
2015/07/21 职场文书
深入浅析Redis 集群伸缩原理
2021/05/15 Redis
为Java项目添加Redis缓存的方法
2021/05/18 Redis
对PyTorch中inplace字段的全面理解
2021/05/22 Python
VS2019连接MySQL数据库的过程及常见问题总结
2021/11/27 MySQL