• 【转】解决PHP在IE浏览器下载文件,中文文件名乱码问题


    今天一个问题:“使用360浏览器和IE 出现文件名称乱码”.

    前提:我们网站所有文件全部使用的是UTF-8 NO BOM的编码方式

    1、找测试重现。360浏览器下载的呵呵,果然文件名是乱码。再请测试在ie浏览器下测试。IE9,8,7也全部是乱码。查看编码就是UTF-8.所名不是编码问题造成的。使用firefox8 测试很正常。猜想是因为ie的某些特殊的设置导致的问题。

    2、以"PHP ie 下载 文件名乱码"为关键字搜索。果然,ie对中文文件名的下载文件是需要特殊处理的。

    3、网上一哥们如是说:

    如果$file_name是UTF-8编码的,比如文件名为测试.html; 
    ie这时就搞些小情绪,文件名变成了乱码了 

    在RFC2231的定义里面, 多语言编码的Content-Disposition应该这么定义: 
    Content-Disposition: attachment; filename*="utf8''%E6%B5%8B%E8%AF%95.html" 
    即: 
    filename后面的等号之前要加 * 
    filename的值用单引号分成三段,分别是字符集(utf8)、语言(空)和urlencode过的文件名。 
    所以这时应该对文件名进行url编码转换 ,使用php的urlencode很轻松就搞定了 

    因此,以上代码应该加上url编码转换

    $file_name = urlencode($file_name);  

    查找代码,找到文件名的地方,判断如果是ie 就对文件名称进行urlencode.

    提交,测试。ok。问题解决。再次,多谢网友的无私奉献。

    ThinkPHP代码:

     1     /**
     2      +----------------------------------------------------------
     3      * 下载文件
     4      * 可以指定下载显示的文件名,并自动发送相应的Header信息
     5      * 如果指定了content参数,则下载该参数的内容
     6      +----------------------------------------------------------
     7      * @static
     8      * @access public
     9      +----------------------------------------------------------
    10      * @param string $filename 下载文件名
    11      * @param string $showname 下载显示的文件名
    12      * @param string $content  下载的内容
    13      * @param integer $expire  下载内容浏览器缓存时间
    14      +----------------------------------------------------------
    15      * @return void
    16      +----------------------------------------------------------
    17      * @throws ThinkExecption
    18      +----------------------------------------------------------
    19      */
    20     static public function download ($filename, $showname='',$content='',$expire=180) {
    21         if(is_file($filename)) {
    22             $length = filesize($filename);
    23         }elseif(is_file(UPLOAD_PATH.$filename)) {
    24             $filename = UPLOAD_PATH.$filename;
    25             $length = filesize($filename);
    26         }elseif($content != '') {
    27             $length = strlen($content);
    28         }else {
    29             throw_exception($filename.L('下载文件不存在!'));
    30         }
    31         if(empty($showname)) {
    32             $showname = $filename;
    33         }
    34 //造成部分中文文件的乱码问题
    35         //$showname = basename($showname);
    36 if(!empty($filename)) {
    37        $type = mime_content_type($filename);
    38 }
    39 if(empty($type)) {
    40        $type="application/octet-stream";
    41 }
    42         //发送Http Header信息 开始下载
    43         header("Pragma: public");
    44         header("Cache-control: max-age=".$expire);
    45         //header('Cache-Control: no-store, no-cache, must-revalidate');
    46         header("Expires: " . gmdate("D, d M Y H:i:s",time()+$expire) . "GMT");
    47         header("Last-Modified: " . gmdate("D, d M Y H:i:s",time()) . "GMT");
    48         header("Content-Length: ".$length);
    49         header("Content-type: ".$type);
    50         header("Content-Disposition: attachment; filename= ".urlencode($showname)." "); // 这里----------
    51 
    52         
    53         header('Content-Encoding: none');
    54         header("Content-Transfer-Encoding: binary" );
    55         if($content == '' ) {
    56             readfile($filename);
    57         }else {
    58         echo($content);
    59         }
    60         exit();
    61     }
  • 相关阅读:
    poj1904 King's Quest
    ACM竞赛须掌握的知识 以及 2个版本的POJ推荐 @ NKOJ discuss 转载的
    poj1466
    C++23中设计模式的factory模式
    poj3667 hotel
    poj1505 Copying Books
    在linux系统中安装VSCode(Visual Studio Code)
    Spring_的jar详细说明
    java开发问题总结4Maven使用问题汇总
    线程同步之信号量(sem_init,sem_post,sem_wait)
  • 原文地址:https://www.cnblogs.com/longhua828/p/php_downfile_to_ie_filename_garbled.html
Copyright © 2020-2023  润新知