Open棟梁Project - マイクロソフト系技術情報 Wiki
ダウンロード処理についての問い合わせが多いのでメモ
誤ったヘッダを付与しないよう、一度クリアし正しいヘッダを付与します。
// HTTPレスポンスのヘッダ&エンティティのクリア Response.Clear();
以降のバッファへの書き込みを停止しHTTPレスポンスを確定させます。
// HTTPレスポンス エンティティ設定の終了 Response.End();
キャッシュを無効化すると、ダウンロード・ファイルを
ダイアログで保存しないと、直接開けない現象があるようです。
// キャッシュ無効化 Response.Cache.SetCacheability(HttpCacheability.NoCache);
Content-Typeヘッダには適切なものを指定する必要があります。
// MIMEタイプ Response.ContentType = "application/pdf";
で動作が異なりますので注意が必要になります。
ファイルとしてのダウンロードを要求する。
//こっちは、専用アプリケーションで開く Response.AppendHeader("Content-Disposition", "attachment;filename=test.pdf");
OLEドキュメントとしてインライン表示を要求する。
(ただし、対応しているアプリケーションに限る)
//こっちは、IEからOLEオブジェクトを開く Response.AppendHeader("Content-Disposition", "inline;filename=test.pdf");
また、Adobe Readerでのインライン表示は、
「PDFをブラウザに表示」環境設定が必要になるようです。
Content-length設定の有無による
動作の違いについて CGIのQ&A【OKWave】
http://okwave.jp/qa/q113178.html
効率・性能が変わることは有り得る。
が、それ以外に大きな問題は無いと考える。
HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html; charset=shift_jis Server: Microsoft-IIS/7.5 Refresh: 1200;URL=xxx.aspx X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Thu, 02 May 2013 04:50:27 GMT Content-Length: 12288
StreamにWriteしているHTMLなどのレスポンスには、
APサーバ側がHTTPヘッダに自動的に付与するものと思われる。
HTTP/1.1 200 OK Cache-Control: private Transfer-Encoding: chunked Content-Type: application/pdf; charset=Shift_JIS Server: Microsoft-IIS/7.5 Refresh: 1200;URL=xxx.aspx Content-Disposition: attachment;filename=e:xxx.pdf X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Thu, 02 May 2013 04:50:29 GMT 69ace %PDF-1.4 %粤マモ 2 0 obj ・・・
StreamにWriteしていないWriteFile?系のレスポンスには、
APサーバ側がHTTPヘッダに自動的に付与しないものと思われる。
.NETのResponse.WriteFile?()メソッドは、
Content-Lengthを自動的に設定しない模様
(HTML出力の場合は自動的に付与される)。
JavaでもHTTPレスポンス・ストリームへの
ファイルの書き出し時のContent-Length設定は自動では無く、
res.setContentLength?()メソッドでの設定が独自に必要になる模様
(HTML出力の場合は自動的に付与される)。
故に、PDF、CSVなどのWriteFile?系のレスポンスの場合、
Content-Lengthが付与されていないケースも多いと言える。
分割ダウンロードの作り込みは、
クライアント-サーバのミドルウェアでも作り込みが甘く問題を起こすことが多い。
このためダウンロード問題が起きた場合、Rangeヘッダーに注目するのも良い。
こちらも同様に、必要に応じて
良くある事例を以下に列挙します。
Adobe Reader側の問題である場合は、MSのサポート対象外になります。
環境によってJavaScriptの window.open()+PDFのインライン表示で、
PDFが表示されず真っ白なblank画面が表示される事例がありました。
対策方法は、
・・・で対応しました。
いろいろ問題が発生するケースがあるようです。
日本語環境のExcelが開くことができるCSVファイルのエンコードは
に限定されています。
このため、
Excelで開かれることを考慮したUTF-8のCSVファイル
を作成する場合は、BOMを付け忘れないようご注意ください。
サンプルコード(BOM付UTF-8)
// HTTPレスポンスのヘッダ&エンティティのクリア Response.Clear(); // HTTPレスポンス ヘッダ再設定 // MIMEタイプを設定 Response.ContentType = "text/csv"; // ダウンロードダイアログを開く Response.AppendHeader("Content-Disposition", "attachment;filename=test.csv"); // UTF-8のBOM(EF BB BF)を先頭につける Response.BinaryWrite(new byte[]{239, 187, 191}); // 文字列をUTF-8のバイナリデータに変換する Response.BinaryWrite(System.Text.Encoding.UTF8.GetBytes("りんご,100円\r\nみかん,50円")); // HTTPレスポンス エンティティ設定の終了 Response.End();
Windows7+Office2007の環境下でIEからHTMLリンクから
WebサーバからExcel(CSV)をダウンロードする際、「保存」ではなく、
「開く」とすると、以下の現象が発生するようになった。
下記で解決可能です。
その他、以下のページに原因と対策が書かれています。
ネットワーク越しでコピーした場合など、NTFS 上に ZoneId? が付与される場合がある。
この ZoneId? を持つファイルを実行する場合にメッセージが表示される。
Windows XP Service Pack 2(以下XP SP2)のInternet Explorer(IE)では、セキュリティ対策の一環として、新たに「ZoneId?(ゾーンID)」と呼ばれる仕組みが導入された。インターネット・ゾーンからダウンロードしたファイルや、Outlook Expressで保存したメールの添付ファイルに対して、ZoneId?と呼ばれる一種の「目印(マーカー)」を付けておき、エクスプローラなどでダブルクリックして実行しようとすると、本当に実行してもよいかどうかがユーザーに対して問い合わせられる機能である。そして、ユーザーが許可した場合にのみプログラムの実行が行われる。従来は、いったんローカルにダウンロードすれば何の制約もなくファイルを実行することができたが、ZoneId?により、インターネット・ゾーンから取得したファイルに対しては、ある程度の制約を課すことができるようになった。
Internet Explorer(IE)では、アクセスする先のWebサイトを「インターネット ゾーン」や「ローカル イントラネット ゾーン」という「ゾーン」で分類し、それぞれ異なるセキュリティ設定を適用することによって、ブラウザの安全性を確保している。例えばインターネット・ゾーンに対しては、実行できるスクリプトやActiveXコントロール、ダウンロード機能などを制限してセキュリティを高くするが、イントラネット・ゾーンに対しては制限を緩和し、ユーザーの業務などに支障が出ないようにする、といった具合である。
Sysinternals にて streams というコマンドが提供されており、
プログラムからZoneId?を削除することができる。
Open棟梁の以下の機能
と干渉することがあります。
詳しくは、利用ガイド(ベターユース、FAQ編)を確認ください。
https://github.com/OpenTouryoProject/OpenTouryoDocuments/blob/master/documents/1_User_Guide/ja-JP/7_User_Guide%28BetterUse_and_FAQ%29.doc
以下、.NET(C#)によるダウンロード処理の例です。
// HTTPレスポンスのヘッダ&エンティティのクリア Response.Clear(); // HTTPレスポンス ヘッダ再設定 // MIMEタイプ Response.ContentType = "application/pdf"; // キャッシュ無効化 Response.Cache.SetCacheability(HttpCacheability.NoCache); //こっちは、専用アプリケーションで開く //Response.AppendHeader("Content-Disposition", "attachment;filename=test.pdf"); //こっちは、IEからOLEオブジェクトを開く Response.AppendHeader("Content-Disposition", "inline;filename=test.pdf"); // HTTPレスポンス エンティティ設定 Response.WriteFile("c:\test.pdf")); // HTTPレスポンス エンティティ設定の終了 Response.End();