HTTP에서 Content-Disposition 헤더의 파일 이름 매개 변수를 인코딩하는 방법은 무엇입니까?


535

웹 브라우저에서 직접 렌더링 하지 않고 자원을 강제로 다운로드 하려는 웹 응용 프로그램 은 다음 형식의 HTTP 응답으로 헤더를 발행합니다 .Content-Disposition

Content-Disposition: attachment; filename=FILENAME

filename매개 변수는 브라우저가 자원을 다운로드 한 파일의 이름을 제안하는 데 사용할 수 있습니다. 그러나 RFC 2183 (Content-Disposition)은 2.3 (파일 이름 매개 변수) 섹션 에 파일 이름에 US-ASCII 문자 만 사용할 수 있다고 명시되어 있습니다.

현재 [RFC 2045] 문법은 매개 변수 값 (및 Content-Disposition 파일 이름)을 US-ASCII로 제한합니다. 파일 이름에 임의의 문자 집합을 허용하는 것이 바람직하지만이 문서에서는 필요한 메커니즘을 정의하지 않습니다.

그럼에도 불구하고 오늘날 가장 널리 사용되는 웹 브라우저는 미국 이외의 ASCII 문자가 아닌 (표준이 없기 때문에) 파일 이름의 인코딩 체계 및 문자 세트 사양에 동의하지 않는 것으로 보입니다. 그렇다면 파일 이름 "naïvefile"(따옴표없이 세 번째 문자가 U + 00EF 인 경우)을 Content-Disposition 헤더로 인코딩해야하는 경우 인기있는 브라우저에서 사용하는 다양한 체계와 인코딩은 무엇입니까?

이 질문의 목적 상 인기있는 브라우저 는 다음과 같습니다.

  • Firefox
  • 인터넷 익스플로러
  • 원정 여행
  • 구글 크롬
  • 오페라

모바일 사파리 (@Martin Ørding-Thomsen이 제안한 원시 UTF-8)에서는 작동하지만 동일한 장치의 GoodReader에서는 작동하지 않습니다. 어떤 아이디어?
Thilo


1
Kornel의 대답 은 경로의 마지막 세그먼트를 설정할 수 있다면 가장 저항이 적은 경로라는 것이 입증되었습니다. 이것과 커플 Content-Disposition: attachment.
Antti Haapala

답변:


94

제안 된 RFC 5987 , "HTTP (Hypertext Transfer Protocol) 헤더 필드 매개 변수에 대한 문자 세트 및 언어 인코딩" 에서 브라우저 테스트 및 이전 버전과의 호환성에 대한 링크를 포함하여 이에 대한 설명이 있습니다.

RFC 2183 은 이러한 헤더가 RFC 2231에 의해 폐기 된 RFC 2184 에 따라 인코딩되어야하며 , 상기 RFC 초안에 포함된다.


5
또한 인터넷 초안 ( "초안 RFC"아님)이 완료되었으며 최종 문서는 RFC 5987 ( greenbytes.de/tech/webdav/rfc5987.html )
Julian Reschke

11
이와 관련하여 파일 이름에 쉼표 (,)가 있으면 Firefox (버전 4-9 포함)가 깨지는 것을 발견했습니다 (예 :) Content-Disposition: filename="foo, bar.pdf". 결과적으로 firefox는 파일을 올바르게 다운로드하지만 .part확장자 (예 :)는 유지합니다 foo,bar.pdf-1.part. 물론 응용 프로그램이와 연결되어 있지 않기 때문에 파일이 제대로 열리지 않습니다 .part. 다른 ASCII 문자는 정상적으로 작동합니다.
catchdave

3
IE 동작에 대한 자세한 내용은 blogs.msdn.com/b/ieinternals/archive/2010/06/07/…를
EricLaw

5
@catchdave : "첨부 파일을 잊어 버렸습니다." 부품.
Christoffer Hammarström

6
결국, 이것은 74 upvotes의 링크 전용 답변 일뿐입니다.
Antti Haapala

364

나는 이것이 오래된 게시물이라는 것을 알고 있지만 여전히 관련이 있습니다. 현대 브라우저는 rfc5987을 지원하며 utf-8 인코딩, 백분율 인코딩 (URL 인코딩)을 허용합니다. 그런 다음 Naïve file.txt는 다음과 같습니다.

Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt

Safari (5)는이를 지원하지 않습니다. 대신 utf-8로 인코딩 된 헤더에 파일 이름을 직접 쓰는 Safari 표준을 사용해야합니다.

Content-Disposition: attachment; filename=Naïve file.txt

IE8 및 그 이전 버전도 지원하지 않으며 utf-8 인코딩의 IE 표준, 백분율 인코딩을 사용해야합니다.

Content-Disposition: attachment; filename=Na%C3%AFve%20file.txt

ASP.Net에서는 다음 코드를 사용합니다.

string contentDisposition;
if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
    contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
else if (Request.Browser.Browser == "Safari")
    contentDisposition = "attachment; filename=" + fileName;
else
    contentDisposition = "attachment; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
Response.AddHeader("Content-Disposition", contentDisposition);

IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5를 사용하여 위의 테스트를 수행했습니다.

2013 년 11 월 업데이트 :

현재 사용중인 코드는 다음과 같습니다. 여전히 IE8을 지원해야하므로 첫 번째 부분을 제거 할 수 없습니다. Android의 브라우저는 내장 된 Android 다운로드 관리자를 사용하며 표준 방식으로 파일 이름을 안정적으로 구문 분석 할 수 없습니다.

string contentDisposition;
if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
    contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
else if (Request.UserAgent != null && Request.UserAgent.ToLowerInvariant().Contains("android")) // android built-in download manager (all browsers on android)
    contentDisposition = "attachment; filename=\"" + MakeAndroidSafeFileName(fileName) + "\"";
else
    contentDisposition = "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
Response.AddHeader("Content-Disposition", contentDisposition);

위의 파일은 다음 파일 이름을 사용하여 IE7-11, Chrome 32, Opera 12, FF25, Safari 6에서 테스트되었습니다. 你好 abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§ !! ^ ~ '-_,;. txt

IE7에서는 일부 문자에서 작동하지만 일부 문자에서는 작동하지 않습니다. 그러나 오늘날 누가 IE7에 관심이 있습니까?

이것은 Android의 안전한 파일 이름을 생성하는 데 사용하는 기능입니다. Android에서 지원되는 문자를 모르지만 이러한 문자가 제대로 작동하는지 테스트했습니다.

private static readonly Dictionary<char, char> AndroidAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-+,@£$€!½§~'=()[]{}0123456789".ToDictionary(c => c);
private string MakeAndroidSafeFileName(string fileName)
{
    char[] newFileName = fileName.ToCharArray();
    for (int i = 0; i < newFileName.Length; i++)
    {
        if (!AndroidAllowedChars.ContainsKey(newFileName[i]))
            newFileName[i] = '_';
    }
    return new string(newFileName);
}

@TomZ : IE7과 IE8에서 테스트했으며 아포스트로피 ( ')를 벗어날 필요가 없다는 것이 밝혀졌습니다. 실패한 예가 있습니까?

@Dave Van den Eynde : RFC6266에 따라 두 줄의 파일 이름을 한 줄에 결합하면 Android 및 IE7 + 8을 제외하고 작동하며 코드를 업데이트했습니다. 제안 해 주셔서 감사합니다.

@Thilo : GoodReader 또는 다른 비 브라우저에 대해서는 전혀 모른다. 안드로이드 접근법을 사용하면 운이 좋을 수도 있습니다.

@ Alex Zhukovskiy : 왜 그런지는 모르겠지만 Connect 에서 논의한 것처럼 끔찍하게 작동하지 않는 것 같습니다.


1
Mobile Safari (위에서 제안한대로 utf-8)에서는 작동하지만 동일한 장치의 GoodReader에서는 작동하지 않습니다. 어떤 아이디어?
Thilo

1
IE7 및 8도 아포스트로피를 이스케이프 처리해야합니다. .Replace ( " '", Uri.HexEscape ('\ ''))
TomZ

1
UTF-8 문자를 직접 쓰는 것은 현재 버전의 Firefox, Chrome 및 Opera에서 작동하는 것 같습니다. Safari & IE를 테스트하지 않았습니다.
Martin Tournoij

20
왜으로, 그들을 결합 Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt; filename=Na%C3%AFve%20file.txt하고 스니핑 브라우저를 건너 뛸? 작동할까요?
Dave Van den Eynde

9
fastmail의 친절한 사람들은 또 다른 해결 방법을 찾았습니다. blog.fastmail.com/2011/06/24/download-non-english-filenames Content-Disposition : attachment; filename = "foo- % c3 % a4.html"; filename * = UTF-8''foo- % c3 % a4.html fileName을 두 번 (UTF-8 접두사없이 한 번과 함께 한 번) 지정하면 IE8-11, Edge, Chrome, Firefox 및 Safari에서 작동합니다 ( 가) 지금뿐만 아니라이 작동하므로, 사과 고정 사파리처럼 보인다
wullinkm

169
  • 에서 비 ASCII 이름을 인코딩하는 상호 운용 가능한 방법은 없습니다 Content-Disposition. 브라우저 호환성은 엉망 입니다.

  • 이론적으로 올바른 구문 UTF-8에서의 사용은 Content-Disposition매우 이상한 : filename*=UTF-8''foo%c3%a4(예, 중간에 비어있는 작은 따옴표를 제외한 별표 및 따옴표있어 그)

  • 이 헤더는 다소 표준이 아닙니다 ( HTTP / 1.1 사양은 그 존재를 인정 하지만 클라이언트가 그것을 지원할 필요는 없습니다).

간단하고 매우 강력한 대안 이 있습니다 . 원하는 파일 이름이 포함 된 URL을 사용하십시오 .

마지막 슬래시 뒤의 이름이 원하는 이름이면 추가 헤더가 필요하지 않습니다!

이 트릭은 작동합니다.

/real_script.php/fake_filename.doc

그리고 서버가 URL 재 작성을 지원하는 경우 (예 : mod_rewriteApache) 스크립트 부분을 완전히 숨길 수 있습니다.

URL의 문자는 바이트 단위로 urlencoded 된 UTF-8 형식이어야합니다.

/mot%C3%B6rhead   # motörhead

3
GetAttachment.aspx / fake_filename.doc? id = 34를 사용해보십시오 (아파치 전용 문제 일 수도 있음)
Kornel

2
이것은 환상적인 해결책입니다. 정말 많은 도움이되었습니다. 감사.
kristopolous

6
나는 토끼 길을 내려 가서 다른 해결책을 시도했다. 헤더를 올바르게 설정하기 위해 올바른 브라우저와 버전을 스니핑하는 것은 너무 악몽입니다. Chrome에서 Safari가 동일하게 작동하지 않는 것으로 잘못 식별했습니다 (올바르게 인코딩되지 않은 경우 쉼표로 구분). 문제를 해결하고이 솔루션을 사용하고 필요에 따라 URL의 별명을 지정하십시오.
mpen

3
/:id/:filename방법은 정말 간단하고 효과적입니다. 감사합니다!
Luca Steeb 1

2
천 번 "예". 당신은 이것으로 시간을 크게 이길 것입니다 더욱이-일부 안드로이드 브라우저는 무시 하고 평평하게 Content-Disposition흥미로운 파일 이름을 만듭니다 (경로에서 생성됩니다). 따라서 건강을 유지하기위한 유일한 해결책 Content-Disposition: attachment은 원하는 파일 이름을 마지막 경로 구성 요소로 설정 하고 전달하는 것입니다.
Julik

73

RFC 6266 은“ HTTP (Hypertext Transfer Protocol)에서 콘텐츠 처리 헤더 필드 사용 ”에 대해 설명합니다 . 그 인용 :

6. 국제화 고려 사항

[ RFC5987 ]에 정의 된 인코딩을 사용하여 " filename*"매개 변수 ( 4.3 절 )를 사용하면 서버가 ISO-8859-1 문자 세트 외부에서 문자를 전송하고 선택적으로 사용중인 언어를 지정할 수 있습니다.

그리고 그들의 예제 섹션에서 :

이 예제는 위의 예제와 동일하지만 RFC 5987을 구현하지 않는 사용자 에이전트와의 호환성을 위해 "filename"매개 변수를 추가합니다 .

Content-Disposition: attachment;
                     filename="EURO rates";
                     filename*=utf-8''%e2%82%ac%20rates

참고 : RFC 5987 인코딩을 지원하지 않는 사용자 에이전트 는“ filename*”다음에 발생하면 “ ”를 무시 합니다 filename.

에서 부록 D 증가 상호 운용성에 대한 제안의 긴 목록도 있습니다. 또한 구현을 비교하는 사이트를 가리 킵니다 . 공통 파일 이름에 적합한 현재 전체 패스 테스트에는 다음이 포함됩니다.

  • attwithisofnplain : 큰 따옴표가 있고 인코딩이없는 일반 ISO-8859-1 파일 이름. 파일 이름은 모두 ISO-8859-1이며 최소한 16 진수 앞에는 백분율 기호를 포함하지 않습니다.
  • attfnboth : 위에서 설명한 순서대로 두 개의 매개 변수. IE8은“ filename”매개 변수를 사용하지만 대부분의 브라우저에서 대부분의 파일 이름에 대해 작동해야합니다 .

즉, RFC 5987 차례 참조에서 RFC 2231 의 실제 형식을 설명합니다. 2231은 주로 메일 용이며 5987은 HTTP 헤더에 사용될 부분을 알려줍니다. RFC 2388 ( 특히 섹션 4.4 ) 및 HTML 5 초안 에 의해 관리되는 multipart/form-dataHTTP 본문 내부에서 사용되는 MIME 헤더와 이것을 혼동하지 마십시오 .


1
Safari에서 문제가 발생했습니다. 러시아어 이름을 가진 파일을 다운로드 할 때 잘못된 문자를 읽을 수 없습니다. 솔루션이 도움이되었습니다. 그러나 헤더를 단일 행으로 보내야합니다 (!!!).
evtuhovdo

16

Jim 이 그의 답변에서 언급 한 RFC 초안 에서 링크 된 다음 문서 는이 질문에 대해 자세히 설명하고 여기에서 직접 참고할 가치가 있습니다.

HTTP 콘텐츠 처리 헤더 및 RFC 2231/2047 인코딩에 대한 테스트 사례


filename 매개 변수를 인코딩하는 두 가지 방법을 제공 할 수 있으며 이전 브라우저와 새 브라우저 (이 경우 MSIE8 및 Safari)에서 제대로 작동하는 것으로 보입니다. @AtifAziz 가 언급 한 보고서에서 attfnboth 를 확인하십시오 .
Pablo Montilla

11

asp.net mvc2에서 나는 다음과 같은 것을 사용한다 :

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

mvc (2)를 사용하지 않으면 다음을 사용하여 파일 이름을 인코딩 할 수 있습니다.

HttpUtility.UrlPathEncode(fileName)

2
파일 이름 인코딩의 URL 인코딩이 유효하지 않으므로 브라우저는 URL 인코딩을 URL로 인코딩해서는 안됩니다.
SerialSeb

IE 11은이 필드에서 URL 인코딩을 해독하지 않습니다.
pseudocoder

그러나 브라우저가 Chrome 또는 IE 인 경우 UrlEncoded가 필요했습니다. FF, Safari 및 Opera와 같은 다른 인코딩은 인코딩
Reza

11

파일 이름을 큰 따옴표로 묶으십시오. 나를 위해 문제를 해결했습니다. 이처럼 :

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

http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

여러 옵션을 테스트했습니다. 브라우저는 사양을 지원하지 않으며 다르게 행동합니다. 큰 따옴표가 가장 좋은 옵션이라고 생각합니다.


3
슬프게도 위의 답변에서 설명한 모든 문제를 해결하지는 못합니다.
Luca Steeb

2
이것은 당신이 공백, 파일 이름을 반환 할 수 있습니다 &, %, #는 그 해결 그래서 등.
Don Cheadle

파일 이름에 큰 따옴표가 포함되어 있으면 어떻게됩니까 (그렇습니다 가능) RFC 6266에 지정된 것처럼 파일 이름은 "따옴표로 묶인 문자열"이며 RFC 2616에 지정된대로 따옴표로 묶은 문자열 안에 큰 따옴표는 백 슬래시로 이스케이프해야합니다.
Christophe Roussy

10

인코딩을 위해 다음 코드 스 니펫을 사용합니다 ( fileName 에 파일의 파일 이름 및 확장자 (예 : test.txt)가 있다고 가정 ).


PHP :

if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], "MSIE" ) > 0 )
{
     header ( 'Content-Disposition: attachment; filename="' . rawurlencode ( $fileName ) . '"' );
}
else
{
     header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode ( $fileName ) );
}

자바:

fileName = request.getHeader ( "user-agent" ).contains ( "MSIE" ) ? URLEncoder.encode ( fileName, "utf-8") : MimeUtility.encodeWord ( fileName );
response.setHeader ( "Content-disposition", "attachment; filename=\"" + fileName + "\"");

오른쪽, 그것이 있어야 rawurlencode에 대한 최소한 PHP에서 filename*=이후 처리 헤더 value-chars에 사용되는 ext-valueRFC 6266-의> RFC 5987 (참조 : tools.ietf.org/html/rfc6266#section-4.1 & tools.ietf.org/html/rfc5987#section -3.2.1 )은 퍼센트 이스케이프 처리가없는 공백을 허용하지 않습니다 ( filename=반면 ASCII 만 있으면되지만 이스케이프 처리가없는 공백을 허용 할 수 있습니다). 몇 문자를 이스케이프 할 수 있도록 그것은 rawurlencode의 전체 엄격로 인코딩 할 필요가 없습니다 : gist.github.com/brettz9/8752120
브렛 Zamir

9

ASP.NET 웹 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;
    }
}

IE 9 수정되지 않음
IE 9 고정


5

호환성 모드를 통해 이전 탐색기를 포함하여 모든 주요 브라우저에서 다음 코드를 테스트했으며 모든 곳에서 잘 작동합니다.

$filename = $_GET['file']; //this string from $_GET is already decoded
if (strstr($_SERVER['HTTP_USER_AGENT'],"MSIE"))
  $filename = rawurlencode($filename);
header('Content-Disposition: attachment; filename="'.$filename.'"');

5

필자는 "download.php"스크립트에서 다음 코드를 작성했습니다 ( 이 블로그 포스트이러한 테스트 사례를 기반으로 함 ).

$il1_filename = utf8_decode($filename);
$to_underscore = "\"\\#*;:|<>/?";
$safe_filename = strtr($il1_filename, $to_underscore, str_repeat("_", strlen($to_underscore)));

header("Content-Disposition: attachment; filename=\"$safe_filename\""
.( $safe_filename === $filename ? "" : "; filename*=UTF-8''".rawurlencode($filename) ));

iso-latin1과 "안전한"문자 만 사용하는 한 filename = "..."의 표준 방식을 사용합니다. 그렇지 않으면 filename * = UTF-8 ''URL 인코딩 방식을 추가합니다. 이 특정 테스트 사례 에 따르면 MSIE9 이상에서 작동하며 최근 FF에서는 Chrome, Safari에서 작동합니다. 낮은 MSIE 버전에서는 ISO8859-1 버전의 파일 이름을 포함하는 파일 이름을 제공해야하며이 인코딩에없는 문자는 밑줄로 표시해야합니다.

최종 메모 : 최대 각 헤더 필드의 크기는 아파치에서 8190 바이트입니다. UTF-8은 문자 당 최대 4 바이트 일 수 있습니다. rawurlencode 이후에는 문자 당 x3 = 12 바이트입니다. 비효율적이지만 이론적으로 파일 이름에 600 개 이상의 "스마일"% F0 % 9F % 98 % 81 이상을 가질 수 있어야합니다.


...하지만 전송 가능한 최대 파일 이름 길이는 클라이언트에 따라 다릅니다. 단지 [89 smiles😁] .pdf 파일 이름이 MSIE11을 통해 얻는다는 것을 알았습니다. Firefox37에서는 최대 [111x 😁] .pdf입니다. Chrome41은 110 번째 미소에서 파일 이름을 자릅니다. 흥미롭게도 접미사는 정상적으로 전송됩니다.
apurkrt

5

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);
}

1
사용하는 것이 좋습니다 encodeURI(str). 파일 이름에 날짜가있는 예 : encodeURIComponent('"Kornél Kovács 1/1/2016')=> "Kornél Kovács 1 % 2F1 % 2F2016"vs. encodeURI('"Kornél Kovács 1/1/2016')=> "Kornél Kovács 1/1/2016"
gdibble

4

PHP에서 이것은 나를 위해했습니다 (파일 이름이 UTF8로 인코딩되었다고 가정).

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

IE8-11, Firefox 및 Chrome에서 테스트되었습니다.
브라우저가 filename * = utf-8을 해석 할 수 있으면 UTF8 버전의 파일 이름을 사용하고 그렇지 않으면 디코딩 된 파일 이름을 사용합니다. 파일 이름에 ISO-8859-1로 표현할 수없는 문자가 포함되어 있으면 iconv대신 사용하는 것이 좋습니다.


3
이 코드가 질문에 대답 할 수 있지만, 질문에 대한 이유 및 / 또는 방법 에 대한 추가 컨텍스트를 제공 하면 장기적인 가치가 크게 향상됩니다. 제발 편집 약간의 설명을 추가 할 답변을.
Toby Speight

2
우와, 위의 코드 전용 답변 중 어느 것도 그렇게 다운 투표하거나 비판하지 않았습니다. 또한 내가 찾은 이유는 IE는 해석하지 않는 파일 이름 * = UTF-8 만이 스크립트가 제공합니까 파일 이름의 ISO8859-1 버전이 필요합니다 : 이미 충분히 잘 대답했습니다. 단지 게으른 PHP를위한 간단한 코드를 만들고 싶었다.
구스타프

질문은 언어에 국한되지 않고 헤더 인코딩을 구현할 때 RFC가 무엇을 고수해야하는지에 따라 하향 조정 된 것으로 생각합니다. 그러나 PHP에 대한이 답변에 감사드립니다.이 코드로 인해 화가났습니다.
j4k3

감사합니다. 이 답변은 질문에 엄격하게 대답하지 않았을 수도 있지만, 내가 찾던 것과 정확하게 파이썬의 문제를 해결하는 데 도움이되었습니다.
Lyndsy Simon

1
사용자가 파일 이름을 제어 할 수 있다면이 코드를 공격 경로로 사용할 수 있다고 확신합니다.
Antti Haapala

3

오늘 고객 문제에 대한 응답으로이 모든 것을 시도한 이후의 업데이트

  • 일본어로 구성된 Safari를 제외하고, 고객이 테스트 한 모든 브라우저는 filename = text.pdf에서 가장 잘 작동했습니다. 여기서 text는 URL 인코딩없이 UTF-8에서 ASP.Net/IIS로 직렬화 된 고객 값입니다. 어떤 이유로, 영어로 구성된 Safari는 utf-8 일본어 이름을 가진 파일을 받아들이고 올바르게 저장하지만 일본어로 구성된 동일한 브라우저는 해석되지 않은 utf-8 문자로 파일을 저장합니다. 테스트 된 다른 모든 브라우저는 URL 인코딩없이 인코딩 된 파일 이름 utf-8을 사용하여 (언어 구성에 관계없이) 최상으로 작동하는 것처럼 보였습니다.
  • Rfc5987 / 8187 구현하는 단일 브라우저를 전혀 찾을 수 없습니다 . 최신 Chrome, Firefox 빌드 및 IE 11 및 Edge로 테스트했습니다. 필자는 filename * = utf-8''texturlencoded.pdf로 헤더를 설정하고 filename = text.pdf로 설정했습니다. filename * = utf-8''texturlencoded.pdf. Rfc5987 / 8187의 어떤 기능도 위의 어느 것도 올바르게 처리되지 않은 것으로 보입니다.

이것은 좋은 업데이트입니다. 시도한 특정 테스트에 대해 자세히 설명해 주시겠습니까?
Brad

3

Symfony 4의 PHP 프레임 워크는 다음 $filenameFallback과 같습니다 HeaderUtils::makeDisposition. 자세한 내용은이 기능을 살펴보십시오. 위의 답변과 비슷합니다.

사용 예 :

$filenameFallback = preg_replace('#^.*\.#', md5($filename) . '.', $filename);
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename, $filenameFallback);
$response->headers->set('Content-Disposition', $disposition);

1

클래식 ASP 솔루션

대부분의 최신 브라우저는 전달되지 지원 Filename으로 UTF-8하지만 지금에 기반 파일 업로드 솔루션 I 사용의 경우와 같이 FreeASPUpload.Net (사이트는 더 이상에, 링크가 가리키는 존재 archive.org ) 의 구문 분석 등이하고자하지 작업 바이너리는 단일 바이트 ASCII 인코딩 문자열을 읽는 데 의존했으며 ASCII가 지원하지 않는 문자에 도달 할 때까지 UTF-8 인코딩 데이터를 전달했을 때 정상적으로 작동했습니다.

그러나 바이너리를 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

크레딧은 내 코드에서 함수를 구현하여 Pure ASP 파일 업로드 로 이동합니다 . 파일 이름 을 얻을 수있었습니다 .BytesToString()include_aspuploader.aspUTF-8


유용한 링크


-1

우리는 웹 응용 프로그램에서 비슷한 문제를 겪었고 HTML에서 파일 이름을 읽고 <input type="file">URL로 인코딩 된 형식으로 새 HTML로 설정 하여 끝났습니다 <input type="hidden">. 물론 일부 브라우저에서 반환되는 "C : \ fakepath \"와 같은 경로를 제거해야했습니다.

물론 이것은 OPs 질문에 직접 대답하지는 않지만 다른 사람들에게 해결책이 될 수 있습니다.


1
완전히 다른 문제. 질문은 다운로드에 관한 것이며 , 귀하의 회신은 업로드 에 관한 것 입니다.
Oskar Berggren 16:25에

-3

일반적으로 파일 이름을 % xx로 URL 인코딩하고 모든 브라우저에서 작동하는 것 같습니다. 어쨌든 몇 가지 테스트를 원할 수도 있습니다.


10
나는 몇 가지 테스트를했는데 모든 브라우저에서 그런 식으로 작동하지 않으므로 질문이 있습니다. :)
Atif Aziz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.