web-dev-qa-db-ja.com

Content-Dispositionファイル名の特殊文字

私の質問は HTTPでContent-Dispositionヘッダーのファイル名パラメーターをエンコードする方法は? の複製ですが、その質問はずっと前に尋ねられたものであり、(私の意見では)まだ満足のいく答えがありません。改めてお聞きしたいのですが。

名前に特殊文字を含めることができるファイルを配信するC++ CGIアプリケーションを開発しています。
奇妙な#€= {}; filename.txt

次のようなすべてのブラウザで機能するようにHTTP Content-Dispostionを設定する可能性はないようです

  • インターネットエクスプローラ
  • Firefox
  • Chrome
  • Opera
  • サファリ

ブラウザごとに異なるソリューションがあれば幸いです。
これが私がどこまで来たかです。

インターネットエクスプローラ (二重引用符を追加し、#と;を置き換えました)

Content-Disposition: attachment; filename="weird %23 € = { } %3B filename.txt"

Firefox (二重引用符は機能しているようです。これ以上何もする必要はありません):

Content-Disposition: attachment; filename="weird # € = { } ; filename.txt"

別の機能する代替:

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt

Chrome

二重引用符のみを使用すると、次の問題が発生します。

  • =ファイル名で消える
  • €は-に置き換えられます

しかし、これは機能します:

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt

Opera

二重引用符を使用するか、構文filename == UTF-8 '' ...を使用すると、次の問題が発生します。

  • ファイル名の複数のくっついたスペースは1つに削減されます
  • {と}が消える: "ab {} cd.txt"->"abcd.txt
  • ファイル名は後に切り捨てられます。初期化: "abc; def.txt"->"abc

編集2: これは、ファイル名の長さの制限が原因でした。この構文はOperaで機能します:

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt

サファリ

  • €は非表示の文字に置き換えられます(二重引用符を使用)

    no solution that prevents that little problem
    

他のスレッド(上記)からの提案

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%80%20%3D%20%7B%20%7D%20%3B%20filename.txt

私にはうまくいきませんでした。エスケープ文字が翻訳されないか、ブラウザがcgiアプリケーションの名前でファイルに保存しようとしています。それは私のエンコーディングが間違っていたからです。 RFC 5987に従ってエンコードしませんでした。しかし、Safariはとにかくこのエンコードを使用していません。したがって、これまでのところ、€文字の解決策はありません。

ところで:UTF-8コンバーター http://www.rishida.net/tools/conversion/

私はこれらのテストのためにすべてのブラウザの最新バージョンを使用しました:

  • Firefox 7
  • Internet Explorer 9
  • Chrome 15
  • Opera 11.5
  • Safari 5.1

PS:キーボードですべての特殊文字を試しました。このスレッドでは、問題が発生したものだけを使用しました。

編集:

私はまた、キーボード上のすべての特殊文字(ファイル名で使用可能)を使用してファイル名を試しましたが、上記のテスト文字列では機能しませんでした。

完全なテスト文字列:

0 ! § $ % & ( ) = ` ´ { }    [ ] ² ³ @ € µ ^ ° ~ + ' # - _ . , ; ü ä ö ß 9.jpg

エンコードされたテスト文字列:

0%20%21%20%C2%A7%20%24%20%25%20%26%20%28%20%29%20%3D%20%60%20%C2%B4%20%7B%20%7D%20%20%20%20%5B%20%5D%20%C2%B2%20%C2%B3%20%40%20%E2%82%AC%20%C2%B5%20%5E%20%C2%B0%20~%20%2B%20%27%20%23%20-%20_%20.%20%2C%20%3B%20%C3%BC%20%C3%A4%20%C3%B6%20%C3%9F%209.jpg

この方法の使用:

Content-Disposition: attachment; filename*=UTF-8''0%20%21%20%C2%A7%20%24%20%25%20%26%20%28%20%29%20%3D%20%60%20%C2%B4%20%7B%20%7D%20%20%20%20%5B%20%5D%20%C2%B2%20%C2%B3%20%40%20%E2%82%AC%20%C2%B5%20%5E%20%C2%B0%20~%20%2B%20%27%20%23%20-%20_%20.%20%2C%20%3B%20%C3%BC%20%C3%A4%20%C3%B6%20%C3%9F%209.jpg

次の結果が得られました。

  • Firefoxは動作します
  • Chromeは機能します
  • IE:$%&()= `´{} []²³@€µ ^°〜+'#-_。 、; üäöß9.jpg(最初の6文字を削除)。 編集2: これは、ブラウザのファイル名の長さの制限が原因でした。文字列の先頭からファイル名を切り取るのが始まりです。これについては詳しく説明しませんでしたが、通常のファイル名は約200文字の長さで、エスケープシーケンスが多いファイル名は250文字よりも多いが少ないようです。しかしそれは問題ありません。
  • Opera:0! §$%&()= `´[]²³@€µ ^°〜+'#-_。 、; üäöß9.jpg(以前のように一部の文字が欠落しています)。 編集2: ファイル名の長さがOperaであるのと同じように、IEで問題がある」と思われ、そこでも機能したため、テスト文字列を短くしました。
  • Safariはその構文では機能しません。それは除外されました。

編集2:

これまでのステータスは、構文 filename * = UTF-8''filnameエスケープシーケンス " Safariを除くすべてのブラウザで動作します。そして、Safariに置き換えられている唯一のキャラクターは€です。私はそれと一緒に暮らすことができると思います。ありがとうございました!

編集3:ファイル名の長さ

ファイル名の長さの問題に気づきました。

  • Internet Explorer:ファイル名は147文字にすることができます。文字列にエスケープシーケンスが含まれていない場合は、それがファイル名の長さです。その場合、ファイル名は変わる可能性があります。結果のファイル名は147文字より短くなります。しかし、それは異なります。 2つのエスケープシーケンスを使用し、ファイル名を5文字に短縮し、多くのエスケープシーケンスとファイル名を使用して、onyl 2文字を短縮しました。ここにルールが見つかりませんでした。
  • 他のブラウザにはその問題はないようです。ファイルシステムがそれを処理できる場合、彼らはファイルを保存します。たとえば、250文字を試しましたが、ブラウザはファイル名(Chrome)を減らす必要があると言ったか、220(Opera)または210(Firefox)文字に短縮しました。 Operaファイルの末尾を切り取ります。Safariはその長いファイル名を保存しようとしましたが、保存せず、ダウンロードリストにファイル名として「-1」を書き込みました。
30
juergen d

Firefox、MSIE(バージョン9以降)、Opera、KonqおよびChromeサポート、MSIE8およびSafariはサポートしていません。その他のサポートは不明です-エンコードはRFC 5987で定義されています。

で注意してください

  Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%80%20%3D%20%7B%20%7D%20%3B%20filename.txt

ユーロ文字のエンコーディングが間違っていました。ユニコードのコードポイントが%80ではないため、これを修正すると、Safari以外のすべての場所で機能します(正しいエンコーディングは%e2%82%acです)。

テストケース:

http://greenbytes.de/tech/tc2231/#attwithfn2231utf8

12
Julian Reschke