解析如何在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中inlcude()性能对比详解
Sep 16 PHP
PHP生成验证码时“图像因其本身有错无法显示”的解决方法
Aug 07 PHP
php随机取mysql记录方法小结
Dec 27 PHP
使用 PHPStorm 开发 Laravel
Mar 24 PHP
浅谈Laravel队列实现原理解决问题记录
Aug 19 PHP
PHP简单实现模拟登陆功能示例
Sep 15 PHP
PHP实现验证码校验功能
Nov 16 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
Mar 31 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
May 23 PHP
PHP获取MySQL执行sql语句的查询时间方法
Aug 21 PHP
详解php协程知识点
Sep 21 PHP
解决laravel5.4下的group by报错的问题
Oct 16 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 性能的检查和优化方法
2009/06/21 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
PHP Class SoapClient not found解决方法
2018/01/20 PHP
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
JavaScript的Cookies
2008/01/16 Javascript
jQuery 自动增长的文本输入框实现代码
2010/04/02 Javascript
Javascript动态引用CSS文件的2种方法介绍
2014/06/06 Javascript
详谈jQuery中的this和$(this)
2014/11/13 Javascript
javascript格式化json显示实例分析
2015/04/21 Javascript
Vue键盘事件用法总结
2017/04/18 Javascript
微信小程序开发之改变data中数组或对象的某一属性值
2018/07/05 Javascript
vue.js实现带日期星期的数字时钟功能示例
2018/08/28 Javascript
ECharts地图绘制和钻取简易接口详解
2019/07/12 Javascript
微信小程序 拍照或从相册选取图片上传代码实例
2019/08/28 Javascript
[01:00:12]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第一场
2018/04/09 DOTA
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
pycharm 使用心得(四)显示行号
2014/06/05 Python
深入学习python的yield和generator
2016/03/10 Python
一个基于flask的web应用诞生 使用模板引擎和表单插件(2)
2017/04/11 Python
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
2017/04/17 Python
opencv 获取rtsp流媒体视频的实现方法
2019/08/23 Python
win10从零安装配置pytorch全过程图文详解
2020/05/08 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
2020/06/05 Python
彪马英国官网:PUMA英国
2019/02/11 全球购物
进程的查看和调度分别使用什么命令
2013/12/14 面试题
会计电算化专业应届大学生求职信
2013/10/22 职场文书
大学生实习证明范本
2014/01/15 职场文书
女儿十岁生日答谢词
2014/01/27 职场文书
科研先进个人典型材料
2014/01/31 职场文书
个人四风问题原因分析及整改措施
2014/09/28 职场文书
企业法人代表授权委托书
2014/10/02 职场文书
2014年教学工作总结
2014/11/13 职场文书
党员活动总结
2015/02/04 职场文书
2015大学自主招生自荐信范文
2015/03/04 职场文书
2015年学校安全管理工作总结
2015/05/11 职场文书
SQL试题 使用窗口函数选出连续3天登录的用户
2022/04/24 Oracle