解析如何在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 08 PHP
php cookie使用方法学习笔记分享
Nov 07 PHP
PHP之APC缓存详细介绍 apc模块安装
Jan 13 PHP
PHP SPL标准库之接口(Interface)详解
May 11 PHP
调试WordPress中定时任务的相关PHP脚本示例
Dec 10 PHP
php修改数组键名的方法示例
Apr 15 PHP
浅谈PHP发送HTTP请求的几种方式
Jul 25 PHP
搜索附近的人PHP实现代码
Feb 11 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
Sep 19 PHP
PHP中通过getopt解析GNU C风格命令行选项
Nov 18 PHP
WordPress多语言翻译插件 - WPML使用教程
Apr 01 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
mysql 搜索之简单应用
2007/04/27 PHP
thinkPHP内置字符串截取函数用法详解
2016/11/15 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
php模式设计之观察者模式应用实例分析
2019/09/25 PHP
laravel 解决ajax异步提交数据,并还回填充表格的问题
2019/10/15 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
不能再简单的无闪刷新验证码原理很简单
2007/11/05 Javascript
jquery each的几种常用的使用方法示例
2014/01/21 Javascript
javascript实现图片循环渐显播放的方法
2015/02/24 Javascript
深入探寻seajs的模块化与加载方式
2015/04/14 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
2016/05/09 Javascript
JavaScript中的冒泡排序法
2016/08/03 Javascript
如何利用模板将HTML从JavaScript中抽离
2016/10/08 Javascript
JS 在数组指定位置插入/删除数据的方法
2017/01/12 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
Node.js使用MySQL连接池的方法实例
2018/02/11 Javascript
js事件on动态绑定数据,绑定多个事件的方法
2018/09/15 Javascript
javascript 模块依赖管理的本质深入详解
2020/04/30 Javascript
[02:18]DOTA2英雄基础教程 育母蜘蛛
2014/01/20 DOTA
[44:50]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第二局
2016/02/26 DOTA
[45:32]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
详解Python编程中包的概念与管理
2015/10/16 Python
使用PYTHON解析Wireshark的PCAP文件方法
2019/07/23 Python
用Python写一个自动木马程序
2019/09/17 Python
Python3常用内置方法代码实例
2019/11/18 Python
Python数组拼接np.concatenate实现过程
2020/04/18 Python
Win 10下Anaconda虚拟环境的教程
2020/05/18 Python
keras.layer.input()用法说明
2020/06/16 Python
python高级特性简介
2020/08/13 Python
塔吉特百货公司官网:Target
2017/04/27 全球购物
Jeep牧马人、切诺基和自由人零配件:4 Wheel Drive Hardware
2017/07/02 全球购物
苹果音乐订阅:Apple Music
2018/08/02 全球购物
财务管理专业毕业生求职信范文
2013/09/21 职场文书
幼儿教师自我鉴定
2013/11/02 职场文书
学习三严三实对照检查材料思想汇报
2014/09/22 职场文书
2015年度培训工作总结范文
2015/04/02 职场文书