質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.19%

ASP.NETでのストリーム経由でのPDF出力について

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,899

ubon

score 67

Window10 Pro 64bit バージョン 1703 OSビルド 15063.413
Chrome/IE11 VS2013 Community Update5環境において 
CrystalReportsにてASP.NETのプログラムを作成しております。

子ウインドウ(A)から、さらにPDF出力用の子ウインドウ(B)をOpenし、
下記の記事を参考に、javascriptによってwindow.open直後に
POSTをするという方法でパラメータを渡して
PDFをストリーム経由で(B)に出力するというプログラムを作成していたところ
Chromeでは問題ないのですが、IE11(11.413.15063.0)では子ウインドウは開くものの
画面が真っ白のまま読み込みが終了してしまいます。

http://qiita.com/tsunet111/items/0167704a65ebc04411f9
※試しにWindows7 32bit のIE11では動作いたしました。

そこで、POSTをやめてGETにてwindow.openをすると
Windows10 IE11で表示されたため、「子ウインドウを開き、POSTする」
というjavascriptの処理の中で対応が必要か?というところで
行き詰っております。

本件CrystalReportsは記載させていただいておりますが
関係ないと判断しております。その根拠としては
・Windows7環境ではChrome/IE11ともに動作確認済みのrptファイルと
PDF出力のロジックをそのまま利用して、window.openの部分を切り替えることによって
現象が発生するかしないかが切り替わることを確認したためです。


2017.06.29 コードを修正しました。
base.aspxをスタートアップとし、baseにあるボタンから、out.aspxでストリーム出力させるサンプルコードです。
<base.aspx> base.aspx.vbファイルは編集無し

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="base.aspx.vb" Inherits="WebApplication1.base" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="content-language" content="ja" />
    <meta http-equiv="x-ua-compatible" content="IE=10" />
    <meta http-equiv="x-ua-compatible" content="IE=EmulateIE10" />    
<title>output test</title>
    <script src="jquery.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function () {

            $('#btn_ok').click(function () {

                window.open('out.aspx?type=hist&rpt_hidP=' + 'dummy', '_blank');

            });

            $('#btn_dame').click(function () {

                window.open('', 'report');

                var form = $('<form/>', {
                    id: 'rpt_p',
                    action: 'out.aspx?type=hist',
                    target: 'report',
                    method: 'post'
                }).append($('<input/>').attr({
                    type: 'hidden',
                    id: 'rpt_hidP',
                    name: 'rpt_hidP',
                    value: 'dummy'
                })
                             );

                $('body').append(form);

                $('#rpt_p').submit();
                $('#rpt_p').remove();

                form = null;

            });

        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <input type="button" id="btn_ok" value="OKパターン" />

        <input type="button" id="btn_dame" value="ダメパターン" />

    </div>
    </form>
</body>
</html>


<out.aspx.vb> ※out.aspxは特に編集無し。sample.pdfは1ページの簡単なpdfを使用。

Imports System
Imports System.IO

Public Class out
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Response.Cache.SetCacheability(HttpCacheability.NoCache)
        Response.Cache.SetNoStore()

        Dim bLength As Byte()

        'ファイルを開く
        Dim fs As New System.IO.FileStream(HttpContext.Current.Server.MapPath("pdf/sample.pdf"), System.IO.FileMode.Open, System.IO.FileAccess.Read)

        'ファイルを読み込むバイト型配列を作成する
        ReDim bLength(fs.Length)
        'ファイルの内容をすべて読み込む
        fs.Read(bLength, 0, Convert.ToInt32(bLength.Length))
        '閉じる
        fs.Close()

        Response.ClearHeaders()
        Response.ClearContent()
        Response.ContentType = "Application/pdf"

        ' ダイアログ表示
        Response.AddHeader("content-disposition", "inline; filename=" & System.Web.HttpUtility.UrlEncode("sample.pdf"))

        ' HTTP 出力ストリームに書き込み
        Response.BinaryWrite(bLength)
        Response.End()

    End Sub

End Class


OKパターン ボタン 結果
Windows10 64bit Chrome ○ IE11 ○
Windows7  32bit Chrome ○ IE11 ○

ダメパターン ボタン 結果
Windows10 64bit Chrome ○ IE11 ×
Windows7  32bit Chrome ○ IE11 ○

上記のサンプルでも再現することからもrptは関係ないと思われます。

さらに、SurferOnWwwさんからアドバイスいただいたようにFiddlerでキャプチャした結果

OKパターンのキャプチャ
リクエストヘッダー GET /out?type=hist&rpt_hidP=dummy HTTP/1.1
レスポンスヘッダー HTTP/1.1 200 OK

ダメパターンのキャプチャ
リクエストヘッダー POST /out.aspx?type=hist HTTP/1.1
レスポンスヘッダー HTTP/1.1 301 Moved Permanently となり下記のような
HTMLが出力された後 Location: /out?type=hist でリダイレクトされているという違いが明らかになりました。

<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/out?type=hist">here</a>.</h2>
</body></html>

Chromeでも同様のキャプチャ結果となりましたが、動作しております。

パラメータが多くなる可能性があるため、できればPOSTで解決したいと
考えております。
対応方法ご存知の方、どうぞよろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ubon

    2017/06/26 17:31

    たびたびのアドバイスありがとうございます。まずはFiddlerで内容確認してみます。ソースは部分的な抜粋です。

    キャンセル

  • SurferOnWww

    2017/06/26 17:40

    部分的な抜粋でもいいですが、ちゃんと動いて問題を再現できるものでないと意味がないです。同じコードを回答者の方でも動かして問題を再現しようとしているわけですから。

    キャンセル

  • SurferOnWww

    2017/06/26 17:42

    先に「Chrome は初期画面表示後は無反応」と書きましたが、それは Chrome のデフォルト設定で警告なしでポップアップをブロックしていたからでした。ポップアップブロックを解除すれば IE と同じ結果になります。

    キャンセル

回答 1

0

何故リダイレクトされるのかの原因は自分はまだ追究できていませんが、その前に確認させてください。

質問者さんが、「ダメパターン ボタン 結果」で、〇 印のブラウザでも「同様のキャプチャ結果」になるのですよね?

つまり、〇 印のブラウザは、サーバーから 301 応答が返ってきた後、応答ヘッダの Location で示された URL を GET 要求にいくのですよね。(リダイレクトの仕組みから GET 要求になるはず)

で、IE11 × の場合はどうなるのでしょう? ブラウザから要求が出ない? サーバーから応答が返ってこない? 応答が返ってきてもブラウザで処理されない?

何にせよ、「ダメパターン ボタン 結果」で 〇 のブラウザでも、リダイレクト後 GET 要求ということになっているのであれば(リダイレクトの仕組みから GET 要求になるはず)、

パラメータが多くなる可能性があるため、できればPOSTで解決したい

ということは、少なくとも今のやり方ではできてないということになるはずなのですが、そこを確認してください。

(根本的にやり方を変えないとダメということになりそうな気がします)

----- 2017/6/29 16:34 追記 -----

下の 2017/06/29 15:48 の私のコメントで「自分の環境と検証に使ったコードその他の情報を回答欄に書いておきます」と書きましたが、それを以下に書いておきます。 

環境:
Visual Studio Commnuty 2015 Update 3
ASP.NET Web Forms(Web サイトプロジェクトとして作成、IIS のサイトに設定)
.NET Framework 4.6.1
Windows 10 Pro 64-bit, 10.0.14393 ビルド 14393
IIS 10.0, CLR v4.0, 64-bit, 統合パイプラインモード
IE11 ver. 11.1358.14393.0 更新 ver. 11.0.43 (KB4021558)

ソースコード

base.aspx に該当するもの。コードビハインド形式にせず一体にしています。

<%@ Page Language="C#" %>

<!DOCTYPE html>

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script src="/Scripts/jquery-1.10.2.js"></script>
    <script type="text/javascript">
        //<![CDATA[
        $(function () {
            $('#btn_ok').click(function () {
                window.open('0008-out.aspx', '_blank');
            });

            $('#btn_dame').click(function () {
                window.open('', 'report');

                var form = $('<form/>', {
                    id: 'rpt_p',
                    action: '0008-out.aspx',
                    target: 'report',
                    method: 'post'
                });

                $('body').append(form);

                $('#rpt_p').submit();
                $('#rpt_p').remove();
            });
        });
    //]]>
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>window.open で開いたウィンドウに pdf をダウンロード</h1>
        <input type="button" id="btn_ok" value="GET" />
        <input type="button" id="btn_dame" value="POST" />
    </div>
    </form>
</body>
</html>

out.aspx.vb に該当するもの。言語は C# です。(ページの名前は 0008-out.aspx としています)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _0008_out : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetNoStore();

        Response.ClearHeaders();
        Response.ClearContent();
        Response.ContentType = "Application/pdf";
        Response.AddHeader("content-disposition", "inline; filename=sample.pdf");
        string path = Server.MapPath("~/app_data/sample.pdf");
        Response.TransmitFile(path);
        Response.End();
    }
}

上記 base.aspx の[POST]ボタンをクリックしたとき、Fiddler で見た要求と応答

要求 (コンテンツは設定してないので空です)

POST http://websiteproject.com/0008-out.aspx HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: http://websiteproject.com/0008-AutoPostByScript.aspx
Accept-Language: ja
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Content-Length: 0
Host: websiteproject.com
Connection: Keep-Alive
Pragma: no-cache

応答

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: Application/pdf
Server: Microsoft-IIS/10.0
content-disposition: inline; filename=sample.pdf
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 29 Jun 2017 07:12:49 GMT
Content-Length: 73552

%PDF-1.4
%äüöß
2 0 obj
<</Length 3 0 R/Filter/FlateDecode>>
stream
・・・以下省略・・・

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/02 20:55

    Win10 64bit Creators Update適用済みの別の端末で試す機会がありましたので追記させていただきますが、IE11 KB4025252にて動作することを確認しました。

    キャンセル

  • 2017/08/02 21:30

    情報をありがとうございました。KB4025252 の適用で解決(pdf が表示されるようになった)という理解でいいのでしょうか?

    キャンセル

  • 2017/08/03 10:43

    あやふやな書き方で申し訳なかったです。
    現状も未解決で、問題のある端末でも再度確認したらIE11 KB4025252でしたので、KBの適用は直接関係ないと思われます。端末個体の設定等に起因する可能性が高いので、引き続き何か分かり次第コメントいたします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる