想要强制下载资源而不是直接在Web浏览器中呈现资源的Web应用程序在表单的HTTP响应中发出Content-Disposition报头:
Content-Disposition:附件;filename = filename
filename参数可用于建议浏览器将资源下载到的文件的名称。然而,RFC 2183 (Content-Disposition)在2.3节(文件名参数)中规定文件名只能使用US-ASCII字符:
当前[RFC 2045]语法限制
参数值(因此
内容-处置文件名)到
us - ascii。我们认可伟大的
允许任意的可取性
文件名中的字符集,但它是
超出了本文档的范围
定义必要的机制。
然而,有经验证据表明,目前大多数流行的Web浏览器似乎允许非us - ascii字符,但(由于缺乏标准)在文件名的编码方案和字符集规范上存在分歧。问题是,如果文件名“naïvefile”(不带引号,第三个字母是U+00EF)需要编码到Content-Disposition报头中,那么流行的浏览器采用了哪些不同的方案和编码?
为了解决这个问题,流行的浏览器是:
谷歌Chrome
Safari
Internet Explorer或Edge
火狐
歌剧
只是一个更新,因为我今天为了回应一个客户的问题而尝试了所有这些东西
With the exception of Safari configured for Japanese, all browsers our customer tested worked best with filename=text.pdf - where text is a customer value serialized by ASP.Net/IIS in utf-8 without url encoding. For some reason, Safari configured for English would accept and properly save a file with utf-8 Japanese name but that same browser configured for Japanese would save the file with the utf-8 chars uninterpreted. All other browsers tested seemed to work best/fine (regardless of language configuration) with the filename utf-8 encoded without url encoding.
I could not find a single browser implementing Rfc5987/8187 at all. I tested with the latest Chrome, Firefox builds plus IE 11 and Edge. I tried setting the header with just filename*=utf-8''texturlencoded.pdf, setting it with both filename=text.pdf; filename*=utf-8''texturlencoded.pdf. Not one feature of Rfc5987/8187 appeared to be getting processed correctly in any of the above.
在ASP。NET Web API,我url编码的文件名:
public static class HttpRequestMessageExtensions
{
public static HttpResponseMessage CreateFileResponse(this HttpRequestMessage request, byte[] data, string filename, string mediaType)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream(data);
stream.Position = 0;
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType =
new MediaTypeHeaderValue(mediaType);
// URL-Encode filename
// Fixes behavior in IE, that filenames with non US-ASCII characters
// stay correct (not "_utf-8_.......=_=").
var encodedFilename = HttpUtility.UrlEncode(filename, Encoding.UTF8);
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") { FileName = encodedFilename };
return response;
}
}