How to encode the filename parameter of Content-Disposition header in HTTP?

前端 未结 18 2100
北荒
北荒 2020-11-21 06:15

Web applications that want to force a resource to be downloaded rather than directly rendered in a Web browser issue a Content-Disposition hea

18条回答
  •  深忆病人
    2020-11-21 07:05

    I ended up with the following code in my "download.php" script (based on this blogpost and these test cases).

    $il1_filename = utf8_decode($filename);
    $to_underscore = "\"\\#*;:|<>/?";
    $safe_filename = strtr($il1_filename, $to_underscore, str_repeat("_", strlen($to_underscore)));
    
    header("Content-Disposition: attachment; filename=\"$safe_filename\""
    .( $safe_filename === $filename ? "" : "; filename*=UTF-8''".rawurlencode($filename) ));
    

    This uses the standard way of filename="..." as long as there are only iso-latin1 and "safe" characters used; if not, it adds the filename*=UTF-8'' url-encoded way. According to this specific test case, it should work from MSIE9 up, and on recent FF, Chrome, Safari; on lower MSIE version, it should offer filename containing the ISO8859-1 version of the filename, with underscores on characters not in this encoding.

    Final note: the max. size for each header field is 8190 bytes on apache. UTF-8 can be up to four bytes per character; after rawurlencode, it is x3 = 12 bytes per one character. Pretty inefficient, but it should still be theoretically possible to have more than 600 "smiles" %F0%9F%98%81 in the filename.

提交回复
热议问题