想要强制下载资源而不是直接在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
火狐
歌剧
如果你使用的是nodejs后端,你可以使用我在这里找到的以下代码
var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''"
+ encodeRFC5987ValueChars(fileName);
function encodeRFC5987ValueChars (str) {
return encodeURIComponent(str).
// Note that although RFC3986 reserves "!", RFC5987 does not,
// so we do not need to escape it
replace(/['()]/g, escape). // i.e., %27 %28 %29
replace(/\*/g, '%2A').
// The following are not required for percent-encoding per RFC5987,
// so we can allow for a little better readability over the wire: |`^
replace(/%(?:7C|60|5E)/g, unescape);
}
PHP框架Symfony 4在HeaderUtils::makeDisposition中有$filenameFallback。
您可以查看这个函数的详细信息-它与上面的答案类似。
使用的例子:
$filenameFallback = preg_replace('#^.*\.#', md5($filename) . '.', $filename);
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename, $filenameFallback);
$response->headers->set('Content-Disposition', $disposition);
经典ASP解决方案
大多数现代浏览器现在都支持将文件名作为UTF-8传递,但我使用的文件上传解决方案是基于FreeASPUpload的。Net(站点已经不存在了,链接指向archive.org),它不会工作,因为二进制解析依赖于读取单字节ASCII编码的字符串,当您传递UTF-8编码的数据时,它工作得很好,直到您得到ASCII不支持的字符。
然而,我能够找到一个解决方案,使代码读取和解析二进制为UTF-8。
Public Function BytesToString(bytes) 'UTF-8..
Dim bslen
Dim i, k , N
Dim b , count
Dim str
bslen = LenB(bytes)
str=""
i = 0
Do While i < bslen
b = AscB(MidB(bytes,i+1,1))
If (b And &HFC) = &HFC Then
count = 6
N = b And &H1
ElseIf (b And &HF8) = &HF8 Then
count = 5
N = b And &H3
ElseIf (b And &HF0) = &HF0 Then
count = 4
N = b And &H7
ElseIf (b And &HE0) = &HE0 Then
count = 3
N = b And &HF
ElseIf (b And &HC0) = &HC0 Then
count = 2
N = b And &H1F
Else
count = 1
str = str & Chr(b)
End If
If i + count - 1 > bslen Then
str = str&"?"
Exit Do
End If
If count>1 then
For k = 1 To count - 1
b = AscB(MidB(bytes,i+k+1,1))
N = N * &H40 + (b And &H3F)
Next
str = str & ChrW(N)
End If
i = i + count
Loop
BytesToString = str
End Function
通过在我自己的代码中实现include_aspuploader.asp中的by睾string()函数,我能够获得UTF-8文件名。
有用的链接
一个ASP经典应用程序中的Multipart/form-data和UTF-8
Unicode, UTF, ASCII, ANSI格式的差异