どのようにエンコードのファイル名のパラメータContent-DispositionのヘッダにHTTP?

StackOverflow https://stackoverflow.com/questions/93551

質問

ウェブアプリケーションしたい力資源を ダウンロード に直接ではなく、 描画される ウェブブラウザ上で発行 Content-Disposition ヘッダのHTTPリダイレクトのHTTPレスポンスの形式:

Content-Disposition: attachment; filename=ファイル名

filename パラメータを使用でき提案することが名前のファイルのリソースをダウンロードによりジーンズのブランド、、、。 RFC2183 (Content-Disposition)しかし、国 2.3項 (ファイル名のパラメータのファイル名を使用することはできますかUS-ASCII文字:

現在の[RFC2045]文法の制限 パラメータ値が Content-Dispositionファイル名) US-ASCII.ることを認識し、 が望を任意の 文字セットファイル名で の範囲を超えてこのマニュアル を定義するのに必要なメカニズム。

が実証し、その一番人気のWebブラウザでは本日も許可証の非US-ASCII文字だが標準で)賛成"のエンコーディング方式と文字セット仕様のファイル名です。問題は、どのように様々なスキームやエンコーディング採用により、人気ブラウザの場合はファイル名"naïvefile"な引用が第三文字はU+00EF)を符号化することにヘッダのContent-Disposition?

この質問は、 人気ブラウザ

  • Firefox
  • Internet Explorer
  • サファリ
  • Google Chrome
  • オペラ
役に立ちましたか?

解決

あの議論では、そのリンクをブラウザの試験との下位互換性を提案 RFC5987, キャラクタセットおよび言語のエンコーディングHypertext Transfer Protocol(HTTP)ヘッダフィールド"という声が上がった。

RFC2183 このヘッダは符号化することによ RFC2184, した過去の遺物による RFC2231, 対象とする案RFCます。

他のヒント

ごきげんよう、トメ子です、古いポストのがするはずですが、ヒトにおいても関係します。思った現代のブラウザを支援rfc5987は、utf-8エンコーディング率符号化されたurlエンコードされた).その素朴file.txt な:

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

Safari(5)ははこれをサポートしていません。代わりに利用するべきであるサファリの基準文書のファイル名を直接utf-8で符号化されたヘッダ:

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

IE8以上をサポートしないのでどちらかを使用する必要があり、家標準utf-8エンコーディング率符号化された:

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,Chrome13、オペラ11日FF5、Safari5.

更新 月2013年

こちらのコード私は現在、利用します。まだまだ支援IE8でいくのです。ここで示されているデータのブラウザ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、Chrome32,劇12日FF25、Safari6、このファイル名をダウンロード:你好abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§!#¤%&()=`@£$€{[]}+^~'-_,;.txt

にIE7ードを動作させることができ一部の文字ますが、全てではありません。が者の利益ばかり考えて行動していIE7現在では?

この機能を使っている安全なファイル名しました。注そのものかわからない、という文字をサポートがあります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やその他の非ブラウザです。"といった一部の運用のAndroidアプローチ.

@Alex Zhukovskiy:なぜだかよくわかりませんが、議論 接続 わないと思うものすごく仕事です。

があり、非常に堅牢な代替: 利用URLが含まれるファイル名をしたい.

が名前の最後のスラッシュがしたいものにする必要がなくなり、より快適なタイトルヘッダー!

このトリック作品:

/real_script.php/fake_filename.doc

手に入れると、サーバがサポートのURL書き換えなど mod_rewrite Apacheしたのきしげたるき)を非表示にするスクリプトです。

文字UrlはUTF-8のurlencodedバイト:

/mot%C3%B6rhead   # motörhead

RFC6266 について述べていコンテンツ等のご利用-処分をヘッダフィールドはHypertext Transfer Protocol(HTTP)".を引用する:

6.国際化への配慮

の"filename*"パラメータ第4.3章)を使用し、エンコード定義 【RFC5987]のサーバに送信文字以外の ISO-8859-1の文字セットとともに、任意の言語を指定 使用中です。

その 例部:

この例と同じですが、上のようなものを加えた"ファイル名" パラメータとの互換性を維持するため、ユーザーエージェントを実施していない RFC5987:

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

注意:そのユーザーエージェントな機種には対応しておりませんの RFC5987 エンコード 無視"filename*"が発生した後"filename”.

付録D またインターネットでの提案の増加の相互運用性.でもポイント サイトを比較し実装.現在のすべてのパスの試験に適して共通のファイル名:

  • attwithisofnplain:平野ISO-8859-1ファイル名をダブルクォートなエンコーディングです。このファイル名はすべてISO-8859-1が含まれない%の看板、少なくともない前の六角レンチできるようにしました。
  • attfnboth:二つのパラメータの順に記述します。はほとんどのファイル名はほとんどすべてのブラウザでは、IE8の利用"filename"パラメータとします。

その RFC5987 に参考文献 RFC2231, を記述する、実際の形式です。2231は主にメール5987ば、どの部品が使用するHTTPヘッダです。な混乱させることMIMEヘッダートしていない multipart/form-data HTTP 本体, る理解されているのは言うまでも RFC2388 (4.4 特に、 HTML5の草案.

次のドキュメントからリンク 案のRFC 上記により Jim 彼の答えを更にアドレスの問題を是非直接、注意が必要です:

テストケースのためのHTTP Content-DispositionヘッダおよびRFC2231/2047エンコード

にasp.net mvc2を使っていて思ったこと。

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

かみ合わせて使用しない場合はmvc(2)だけなのにエンコードのファイル名を使用

HttpUtility.UrlPathEncode(fileName)

のファイル名をダブルクォート.問題点を解決しました。このように:

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

http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

私試験は複数のオプションブラウザをサポートしていないの仕様および法が異なると思いダブルクォートは最高のオプションです。

使うには、次のコードスニペットをエンコーディングを想定 ファイル名 を含むファイル名と拡張子ファイルの例: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 ) );
}

Java:

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

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

IE 9 Not fixed
IE 9 Fixed

いたしまし以下のコードは、webブラウザを含む高齢探検隊(互換モード)で作品ありとあらゆるところで活躍:

$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.'"');

をご利用の場合は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);
}

その結は、下記コードを私"download.php"スクリプト(基 このblogpostこれらのテストケース).

$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の"安全"に登場するキャラクターを使用しない場合は、追加のファイル名*=UTF-8でurlエンコードされた。による この特定のテストケース, だからMSIE9、最近のFF、Chrome、Safari;下行版ではファイル名を含むはiso8859-1のファイル名をアンダースコア(_)にない文字がこのエンコーディングです。

【注意事項】のmax.サイズ毎にヘッダフィールドは8190バイトにapache.UTF-8できる最大バイトはキャラクター;後rawurlencodeでx3=12バイト単ることができます。写効率の悪いものであるべきだと思う理論的には可能で600以上の"笑顔"%F0%9%98%81のファイル名を指定します。

PHPかったことでまるのもったいなかったと仮定してファイル名はUTF8エンコードされた):

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

に対してテストされていIE8-11、Firefox、Chrome.
場合にはブラウザに解釈する ファイル名*=utf-8 ではUTF8のファイル名この復号化されたファイル名を指定します。場合はファイル名を含むできない文字で表される、ISO-8859-1が使用 iconv です。

クラシックASP液

最近のブラウザー支援の Filename として 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

信用く 純ASPファイルのアップロード 事業の実施により BytesToString() 機能から include_aspuploader.asp 自分のコードを得ることができたの UTF-8 ファイル名です。


役立つリンク

で更新を行いしようとしていたことも、今日に応じてお客様の課題

  • 以外のサファリの設定のための日本語、すべてのブラウザをお客様に試験したテストファイル名=。pdf-テキストがお客様価値の直列化されるASP.Net/IIS utf-8でなくurlエンコーディングです。何らかの理由でサファリの設定のための英語を受諾したものとみなされ、適切に保存ファイルをutf-8日本語の名前が同じブラウザの設定のための日本のように保存ファイルをutf-8文字を未解釈.その他のブラウザでは試験がベスト-ファインのみならず、言語設定をファイル名をutf-8で暗号化されなくurlエンコーディングです。
  • を見つけられなかった単一のブラウザの実施Rfc5987/8187 全ての.いたしまし最新のChrome、FirefoxをプラスIE11びます。また設定のヘッダとファイル名*=utf-8"texturlencoded.pdfの設定で両方のファイル名=。pdfファイル名*=utf-8"texturlencoded.pdfとしています。ないのが特徴ですRfc5987/8187に登場することで知られているが正しく処理されずに。

また同様の問題は、webアプリケーション結果による読書のファイルからHTML <input type="file">, 設定のurlエンコード形式で新しいHTML <input type="hidden">.もちろんまったパスを削除しよう"C:\fakepath"と返される一部のブラウザを推奨いたします。

もちろんのことは直接回答OPs問題も解決策です。

まURLエンコード(%xx)のファイル名で、うすべてのブラウザを推奨いたします。するためにいくつかの試験。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top