Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome cannot recognize url encoded filename while downloading

I tried to download a file with filename GB2312%D5%D5%C6%AC.JPG from my site, everything goes well in IE9/Firefox, but not in Google Chrome.

In Google Chrome, this filename is replaced by my download page name (Maybe Chrome is failed to decode the filename).

To find out if Chrome is tring to decode filename, I tried to use another string GB2312%2C%2D%2E.txt as the filename, firefox/IE9 still work as expected, but Google Chrome will try to decode this filename (replace %2D with '-').

How to prevent Google Chrome from decoding filename? Better if I can solve this problem at my server side (PHP)

The following lines are response headers generated by my server.

**Response Headers:**
Cache-Control:must-revalidate, post-check=0, pre-check=0, private
Connection:keep-alive
Content-Description:File Transfer
Content-Disposition:attachment; filename="GB2312%D5%D5%C6%AC.JPG"
Content-Length:121969
Content-Transfer-Encoding:binary
Content-Type:application/force-download; charset=UTF-8
Date:Wed, 18 Apr 2012 03:32:30 GMT
Expires:0
Pragma:public
Server:nginx/1.1.5
X-Powered-By:PHP/5.3.8
like image 230
sailing Avatar asked Apr 18 '12 03:04

sailing


1 Answers

I just had this very problem. This question was helpful.

The cause is, as you pointed out, that Chrome is trying to decode it and it's outside of ASCII. I would call it a bug, personally.

Basically the answer to get it working in Chrome is to use this:

Content-Disposition:attachment; filename*=UTF-8''GB2312%D5%D5%C6%AC.JPG

However, this will break it in IE8 and Safari. Ugh! So to get it working in those as well, try doing it like this example.

Content-Disposition:attachment; filename="GB2312%D5%D5%C6%AC.JPG"; filename*=UTF-8''GB2312%D5%D5%C6%AC.JPG

For me, I had to url encode the file name before putting it in the filename*=UTF-8 part. So my values for the first file name and the second one aren't the same. I used PHP and my code looks like this:

$encodedfilename = urlencode($downloadfilename);
header("Content-Disposition: attachment; filename=\"$downloadfilename\"; filename*=UTF-8''$encodedfilename");

So I'm not actually stopping it from encoding like you asked for, but I encode it and then pass the parameter that gets decoded by Chrome, back to what it's supposed to be.

like image 160
Andrew Avatar answered Nov 03 '22 14:11

Andrew