解析如何在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 FLEA中二叉树数组的遍历输出
Sep 26 PHP
php5.3中连接sqlserver2000的两种方法(com与ODBC)
Dec 29 PHP
PHP开发工具ZendStudio下Xdebug工具使用说明详解
Nov 11 PHP
php+mysqli实现批量执行插入、更新及删除数据的方法
Jan 29 PHP
php正则匹配文章中的远程图片地址并下载图片至本地
Sep 29 PHP
PHP下载远程图片并保存到本地方法总结
Jan 22 PHP
PHP+HTML+JavaScript+Css实现简单爬虫开发
Mar 28 PHP
laravel中的错误与日志用法详解
Jul 26 PHP
php获取今日开始时间和结束时间的方法
Feb 27 PHP
使用PHP json_decode可能遇到的坑与解决方法
Aug 03 PHP
详解PHP如何更好的利用PHPstorm的自动提示
Aug 18 PHP
php+websocket 实现的聊天室功能详解
May 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
人大复印资料处理程序_输入篇
2006/10/09 PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
phpexcel导出excel的颜色和网页中的颜色显示不一致
2012/12/11 PHP
php创建sprite
2014/02/11 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
thinkPHP5分页功能实现方法分析
2017/10/25 PHP
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
2021/03/09 HTML / CSS
javascript 打开页面window.location和window.open的区别
2010/03/17 Javascript
document.createElement()用法及注意事项(ff下不兼容)
2013/03/13 Javascript
jQuery模拟爆炸倒计时功能实例代码
2017/08/21 jQuery
JQuery选中select组件被选中的值方法
2018/03/08 jQuery
vueJs实现DOM加载完之后自动下拉到底部的实例代码
2018/08/31 Javascript
[54:58]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第一场 11.25
2020/11/25 DOTA
Python中for循环详解
2014/01/17 Python
Python解析网页源代码中的115网盘链接实例
2014/09/30 Python
Python实现的简单dns查询功能示例
2017/05/24 Python
CentOS下使用yum安装python-pip失败的完美解决方法
2017/08/16 Python
Python遍历pandas数据方法总结
2018/02/09 Python
python之cv2与图像的载入、显示和保存实例
2018/12/05 Python
Python实现的删除重复文件或图片功能示例【去重】
2019/04/23 Python
Pandas之DataFrame对象的列和索引之间的转化
2019/06/25 Python
Python generator生成器和yield表达式详解
2019/08/08 Python
Python 调用有道翻译接口实现翻译
2020/03/02 Python
Python多分支if语句的使用
2020/09/03 Python
使用python-cv2实现Harr+Adaboost人脸识别的示例
2020/10/27 Python
CSS3的first-child选择器实战攻略
2016/04/28 HTML / CSS
大学生职业规划前言模板
2013/12/27 职场文书
客户服务经理岗位职责
2014/01/29 职场文书
管事部库房保管员岗位职责
2014/02/21 职场文书
领导接待方案
2014/03/13 职场文书
请假条的格式
2014/04/11 职场文书
社区文化建设方案
2014/05/02 职场文书
航空学院求职信
2014/06/11 职场文书
出纳试用期自我鉴定范文
2014/09/16 职场文书
服务员岗位职责
2015/02/03 职场文书