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

前端 未结 18 1747
北荒
北荒 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 06:52

    In PHP this did it for me (assuming the filename is UTF8 encoded):

    header('Content-Disposition: attachment;'
        . 'filename="' . addslashes(utf8_decode($filename)) . '";'
        . 'filename*=utf-8\'\'' . rawurlencode($filename));
    

    Tested against IE8-11, Firefox and Chrome.
    If the browser can interpret filename*=utf-8 it will use the UTF8 version of the filename, else it will use the decoded filename. If your filename contains characters that can't be represented in ISO-8859-1 you might want to consider using iconv instead.

    0 讨论(0)
  • 2020-11-21 06:52

    Classic ASP Solution

    Most modern browsers support passing the Filename as UTF-8 now but as was the case with a File Upload solution I use that was based on FreeASPUpload.Net (site no longer exists, link points to archive.org) it wouldn't work as the parsing of the binary relied on reading single byte ASCII encoded strings, which worked fine when you passed UTF-8 encoded data until you get to characters ASCII doesn't support.

    However I was able to find a solution to get the code to read and parse the binary as 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
    

    Credit goes to Pure ASP File Upload by implementing the BytesToString() function from include_aspuploader.asp in my own code I was able to get UTF-8 filenames working.


    Useful Links

    • Multipart/form-data and UTF-8 in a ASP Classic application

    • Unicode, UTF, ASCII, ANSI format differences

    0 讨论(0)
  • 2020-11-21 06:53

    The following document linked from the draft RFC mentioned by Jim in his answer further addresses the question and definitely worth a direct note here:

    Test Cases for HTTP Content-Disposition header and RFC 2231/2047 Encoding

    0 讨论(0)
  • 2020-11-21 06:54

    There is discussion of this, including links to browser testing and backwards compatibility, in the proposed RFC 5987, "Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters."

    RFC 2183 indicates that such headers should be encoded according to RFC 2184, which was obsoleted by RFC 2231, covered by the draft RFC above.

    0 讨论(0)
  • 2020-11-21 06:55

    Put the file name in double quotes. Solved the problem for me. Like this:

    Content-Disposition: attachment; filename="My Report.doc"
    

    http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

    I've tested multiple options. Browsers do not support the specs and act differently, I believe double quotes is the best option.

    0 讨论(0)
  • 2020-11-21 06:57

    in asp.net mvc2 i use something like this:

    return File(
        tempFile
        , "application/octet-stream"
        , HttpUtility.UrlPathEncode(fileName)
        );
    

    I guess if you don't use mvc(2) you could just encode the filename using

    HttpUtility.UrlPathEncode(fileName)
    
    0 讨论(0)
提交回复
热议问题