• 追加された行はこの色です。
  • 削除された行はこの色です。
''現在執筆中です。''

*ファイルをダウンロードできるようにする [#vc8f7de4]

ここではサーバーにあるファイルをダイアログを表示して、Webブラウザでダウンロードできるようにする方法を紹介します。

レスポンスヘッダに"Content-Disposition"フィールドを追加し、HttpResponse.WriteFileメソッドで書き込みます。"Content-Disposition"については、[[RFC1806>http://www.ietf.org/rfc/rfc1806.txt]]をご覧ください。

次のコードを実行すると、Internet Explorerでは、「ファイルのダウンロード」ダイアログが表示され、デフォルトでファイル名が「test.txt」で保存されるようにしています。このコードは、ページクラスに記述されているものとします。

#code(vbnet){{
}}

#code(csharp){{
//ダウンロードするファイルのパス
string downloadPath = this.Server.MapPath("test.txt");
//保存時に提案するデフォルトのファイル名
string downloadName = "test.txt";

this.Response.Clear();
//MINE型を指定する
this.Response.ContentType = "application/octet-stream";
//Content-Dispositionヘッダを追加する
this.Response.AddHeader("Content-Disposition",
    "attachment; filename=" + downloadName);

//ファイルを書き込む
this.Response.WriteFile(downloadPath);
//.NET 1.1 SP1以降では次のようにするとよい
//this.Response.TransmitFile(downloadPath);

//送信して終了
this.Response.End();
}}

#column(注意){{
WriteFileメソッドではサイズの大きいファイルを指定することができません。回避法に関しては、「[[PRB: Response.WriteFile Cannot Download a Large File>http://support.microsoft.com/kb/812406/]]」や「[[[FIX] サイズの大きなファイルをダウンロードすると、大量のメモリが失われ、Aspnet_wp.exe プロセスが繰り返される>http://support.microsoft.com/kb/823409/]]」で紹介されています。これらによると、上記コードのコメントで示したようにTransmitFileメソッドを使うか、FileStream.Readメソッドを使って少しずつファイルを読み込み、HttpResponse.BinaryWriteメソッド(もしくは、OutputStream.Writeメソッド)で書き込むようにします。
}}

一般的には、"Content-Disposition"があり、"ContentType"が"application/octet-stream"となっている場合に「名前をつけて保存」ダイアログが表示されることになっています。しかし実際には、これでは正常に機能しないケースが多いようです。特にIE5.5以前では、問題が多いようです。よって"ContentType"を"application/download"や"application/octet-stream-dummy"などの意味のないものに変えた方が確実かもしれません。

また、上記の例では"ContentType"を"application/octet-stream"としていますが、適当なMINE型が分かっているのであれば、それを指定してもかまいません。例えば、テキストファイルでは、"text/plain"です。

**保存ファイル名について [#p1ed35cb]

Content-Dispositionで指定されたファイル名が必ずつけられて保存される保障はありません。そもそもファイル名を強制して保存することはセキュリティ面で問題です。

Content-Dispositionで指定するファイル名にはASCII文字しか使えません。それ以外の文字についてはRFC2231で定義されていますが、この方法では、少なくともIEでは、うまくいきません。「[[[PRB] AddHeader, AppendHeader で日本語ファイル名が文字化けする>http://support.microsoft.com/kb/436616]]」によると、HttpUtility.UrlEncodeメソッドを使うことによりある程度回避できるということですが、絶対的な解決法でないため、ファイル名に日本語を指定するのはやめるべきです。

***参考 [#t2d86cfb]

-[[添付ファイルにおける日本語のファイル名に関して>http://www.emaillab.org/essay/japanese-filename.html]]
-[[[Studying HTTP] HTTP Header Fields>http://www.studyinghttp.net/header#Content-Disposition]]

**上記以外のContent-Dispositionに関するIEのバグ [#wb782970]

上記の問題以外に、IEのバージョンによっては、Content-Dispositionが150バイト以上だとエラーが出るという問題もあります。

-[[エラー メッセージ : "Internet Explorer では、サイト名 - ファイル名 をダウンロードできません。">http://support.microsoft.com/kb/816868]]

また、IE5.5以前では、Content-Dispositionの「attachment」の代わりに「inline」を使わなければ正常に機能しないという話もあります。

これら以外にも、以下のような問題があります。

-[[Internet Explorer で [ファイルのダウンロード] ダイアログ ボックスが 2 つ表示される>http://support.microsoft.com/default.aspx?scid=kb;ja;238588]]
-[[[FIX] Content-Disposition: Attachment の使用時、拡張子が不明な場合に誤ったファイル名で保存される>http://support.microsoft.com/kb/262042]]
-[[[FIX] 既知の内容の種類に対して "Content-Disposition: Attachment" が機能しない>http://support.microsoft.com/kb/267991]]
-[[FIX: Content-Disposition: Does not Force File Download Dialog>http://support.microsoft.com/kb/182315]]
-[[[IE] Content-Disposition: attachment でファイルをダウンロードするとフレームが更新されなくなる>http://support.microsoft.com/kb/418126]]
-[[[ファイルを開く] または [ファイルの保存] ダイアログ ボックスに表示されるファイル名が正しくない>http://support.microsoft.com/default.aspx?scid=kb;ja;238588]]
-[[[FIX] ファイルのダウンロードを何回か中止すると IE が応答しなくなる>http://support.microsoft.com/default.aspx?scid=kb;ja;266305]]
-[[[IE] [開く] および [名前を付けて保存] ダイアログ ボックスで、複数のピリオドの付いたファイルに対して修飾されたファイル名が使用される>http://support.microsoft.com/default.aspx?scid=kb;ja;325630]]
-[[マイクロソフトサイト内の"Content-Disposition"の検索>http://search.microsoft.com/search/results.aspx?view=ja-jp&st=b&na=82&qu=Content-Disposition]]

**参考 [#e688749f]
-[[[HOWTO] 既知の MIME タイプに対し [ファイルのダウンロード] ダイアログ ボックスを開く>http://support.microsoft.com/kb/260519]]
-[[ファイルのダウンロードダイアログで表示されるファイル名の命名規則>http://support.microsoft.com/default.aspx?scid=kb;ja;436153]]
-[[FIX: ASP.NET で Response.Addheader メソッドを使用すると、応答ヘッダーが UTF-8 として常にエンコードされます。>http://support.microsoft.com/default.aspx?scid=kb;ja;895262]]

//これより下は編集しないでください
#pageinfo(,2007-11-08 (木) 03:42:25,DOBON!,2007-11-08 (木) 03:42:25,DOBON!)


[ トップ ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]