2

在我的网络电子邮件服务器上,用户可以从他们的电子邮件中下载附件。

当他们收到一个不是英文的文件名时,文本在 IE 8/9 中会被破坏,但在 Chrome/Firefox 中却完全正常。这是当前处理下载的代码:

<%
    attachfile = request("file")%>
<%
    files = Split(attachfile,"\")
    Set fso = CreateObject("Scripting.FileSystemObject")

    Response.Clear
    'Response.CharSet="UTF-8" 
    Response.ContentType = "application/unknown"
    Response.AddHeader "Pragma", "no-cache"
    Response.AddHeader "Expires", "0"
    Response.AddHeader "Content-Transfer-Encoding", "binary"
    Response.AddHeader "Content-Disposition","attachment; filename = " & files(Ubound(files)) 

    Set objStream = Server.CreateObject("ADODB.Stream")
    objStream.Open

    objStream.Type = 1 
    objStream.LoadFromFile attachfile

    Response.BinaryWrite objStream.Read
    Response.Flush

    objStream.Close : Set objStream = nothing

    Set fso = Nothing
%>
</BODY>
</HTML>

因此,我将文件名在 content-disposition 中传递的方式更改为以下内容,希望它在保存到客户端计算机之前正确地以 UTF-8 编码字符串:

Response.AddHeader "Content-Disposition","attachment; filename = " & Server.URLEncode(files(Ubound(files))) 

现在我已经解决了一个问题,但我面临着两个新问题-_-

第一个问题是当我在 IE 8/9 中下载文件时文件名不再损坏,但它在文件扩展名的末尾添加了一个奇怪的 [1] 或 [2]。因此,如果我有 파일 1.docx,IE 会将文档保存为 파일 1.docx[1]

第二个问题是,在 chrome 中,浏览器从字面上获取 UTF-8 编码的字符串,因此它被保存为 파일%20%1.docx。请注意,文件的非英文部分显示正确,但空白区域显示为 Unicode 字符代码 20。

我该如何解决这个问题?

4

2 回答 2

2

解决方案

最兼容浏览器的方法似乎是将所需的文件名放入 url,而不是Content-Disposition响应头。

例如:

http://localhost/[webpage]/파일.docx

当用户单击上面的链接时,它将保存正确的文件名。以下来自 IE 8:

IE 8 文件下载提示

所以问题就变成了——你如何让asp识别具有上述格式的url?答案是您使用 url 重写器。

如果您使用的是 IIS 4 或更早版本,我强烈建议您升级。

我没有太多使用 URL 重写器的经验,但我能够让 Microsoft 轻松地工作。我使用向导添加了一条user-friendly规则:

添加用户友好的规则对话框

规则本身很简单:

IIS 重写规则设置

如您所见,我正在创建一个重写的规则

http://localhost/default2/foo.doc/
http://localhost/default2/foo.doc (also works)

http://localhost/default2.asp?f=foo.doc

当调用网页(default2.asp)时,它可以从 url 参数中获取文件名f

与您的问题无关,但您可能还需要进行一些身份验证以确保只有适当的用户才能访问文件链接,从而访问您的文件。

来源

如何在 HTTP 中对 Content-Disposition 标头的文件名参数进行编码?

如何为 HTTP 标头编码 UTF8 文件名?(Python,Django)

于 2013-01-24T18:47:11.587 回答
1

作为脚本方面的解决方案,首先需要处理请求的浏览器是否是 Internet Explorer(听起来很熟悉,不是吗?)。
我试图在评论中做出解释。请同时考虑以下示例并在所有主要浏览器中进行测试。

Sub AddDisposHdr(ByVal FileName)
    If InStr(Request.ServerVariables("HTTP_USER_AGENT"), "MSIE") Then 'Internet Explorer
        Dim FileExt
        If InStr(FileName, ".") > 1 And Len(FileName) > 2 Then 'handling files without extension
            'file extension. shouldn't be encoded to get rid of meaningless square brackets in file names
            FileExt = Mid(FileName, InStrRev(FileName, "."))
            FileName = Mid(FileName, 1, InStrRev(FileName, ".") - 1) 'file name without extension
            FileName = Replace(Server.URLEncode(FileName), "+", " ") 'urlencode + replace plus signs with spaces
            FileName = FileName & FileExt
        End If
        Response.AddHeader "Content-Disposition", "attachment; filename=""" & FileName & """"
    Else ' Not Internet Explorer
        'According to RFC 2231 @ http://tools.ietf.org/html/rfc2231#section-3
        Response.AddHeader "Content-Disposition", "attachment; filename*=UTF-8''" &  _ 
        Server.URLPathEncode(FileName) ' It's an undocumented method.
        'Server.UrlPathEncode is used specifically to encode path names.
        'Its difference from UrlEncode is encodes space as "%20" not "+" 
        'and it doesn't encode the following characters at all : $#!&*.+-/@:? but UrlEncode does.
    End If
End Sub

Response.ContentType = "application/x-download"
AddDisposHdr FileNames("こんにちは 1.zip")
Response.Write "1" 'something to output
于 2013-01-25T14:02:53.943 回答