none
ASP.NETでセットしたCookieをJavaScriptで参照する RRS feed

  • 質問

  • 開発環境
    ・Windows7 SP1 x86/x64
    ・VS2008 .NET Framework3.5 
    ・ブラウザ:IE9,10

    実現したいこと
    ・サーバーからのResponse.CookieをクライアントでJavaScriptで取得
    (本当に実現したいことは、ClientScriptManager でセットしたJavaScriptをcookieの値を利用して
    ブラウザの戻るボタンを押されたときに、再度表示されないように制御すること…の手始めとしての上記)

    サーバーサイドで
    var cookie = new HttpCookie("TEST");
    cookie.Value = "true";
    cookie.Expires = DateTime.MaxValue;
    this.Response.Cookies.Set(cookie);
    といったコードでレスポンスにCookieをセットします。
    このセットしたcookieをJavaScriptで取得したいのですが、取得できません。

    IEのデベロッパーツール→キャッシュ→Cookie表示で確認すると、
    Name:Test
    Value:true
    というCookieが存在しています。

    しかし、次のコードでCookieを参照して表示させようにも、値を取得できません。
    return confirm(document.cookie)

    デベロッパーツール上のウォッチリストに
    document.cookie
    と入れても結果は空文字列でした。

    どなたかご存知のかたがいらっしゃいましたら、ご教授いただけませんでしょうか。

    <これまでの主な参考URL>

    http://d.hatena.ne.jp/ku__ra__ge/20090223/p1

    http://www.crystal-creation.com/web-appli/technical-information/programming/javascript/cookie/

    • 編集済み frtakao 2013年7月24日 1:45
    2013年7月24日 1:40

回答

  • ハズレだったようですみません。

    自分の開発環境で、下のコードで試してみました(コード中に「WebBrowser による Cookie取得のテスト」とあるのは気にしないでください)。結果、document.cookie で問題なく取得できました。

    当方の環境は Windows Vista Ultimate SP2 + IE9, ASP.NET 4, IIS7, Visual Studio 2010 Pro です。

    どこかやり方が違うのでは?

    ちなみに、応答ヘッダに含まれる Cookie の設定を Fiddler で見ると以下のようになっています。

    Set-Cookie: ASP.NET_SessionId=yqq4f33gmnvckisn4hxe2qlx; path=/; HttpOnly
    Set-Cookie: DateTimeCookie=2013/07/24 13:24:13; path=/
    Set-Cookie: RandomNumber=374235307; path=/
    Set-Cookie: TEST=true; expires=Fri, 31-Dec-9999 23:59:59 GMT; path=/

    スクリプト document.getElementById("div1").innerHTML = allCookies; の結果は以下の通りとなります。(上の値と違うのは気にしないでください。取得したタイミングが違うので)

    TEST=true; DateTimeCookie=2013/07/24 13:28:53; RandomNumber=1517325953

    なお、HttpOnly 属性を持つ Cookie(上の例では ASP.NET_SessionId)はクライアントスクリプトでは取得できません。理由は、IE6 以降でクロスサイトスクリプティング対応のため HttpOnly 属性が追加され、その属性を持つ HTTP Cookie にはクライアントスクリプトからアクセスできなくなっているからだそうです。

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        protected void Page_Load(object sender, EventArgs e)
        {
            HttpCookie myCookie = new HttpCookie("DateTimeCookie");
            myCookie.Value = DateTime.Now.ToString();
            Response.Cookies.Add(myCookie);
    
            myCookie = new HttpCookie("RandomNumber");
            Random rand = new Random();
            myCookie.Value = rand.Next().ToString();
            Response.Cookies.Add(myCookie);
    
            // 2013/7/24 MSDN Forum の検証用に追加
            // http://social.msdn.microsoft.com/Forums/ja-JP/387822b0-010d-451c-82b4-8f9eb3c75ffc/aspnetcookiejavascript
            var cookie = new HttpCookie("TEST");
            cookie.Value = "true";
            cookie.Expires = DateTime.MaxValue;
            this.Response.Cookies.Set(cookie);
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>WebBrowser による Cookie取得のテスト</title>
        <script type="text/javascript">
        //<![CDATA[
            window.onload = function () {
                var allCookies = document.cookie;
                document.getElementById("div1").innerHTML = allCookies;
            }
        //]]>
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <h1>WebBrowser による Cookie 取得のテスト</h1>
            <div id="div1"></div>
        </div>
        </form>
    </body>
    </html>




    • 編集済み SurferOnWww 2013年7月24日 5:03 環境に IE9 追加
    • 回答としてマーク frtakao 2013年7月24日 7:02
    2013年7月24日 4:48

すべての返信

  • 検証してませんが・・・

    試しに、

    cookie.Expires = DateTime.MaxValue;

    を、

    cookie.Expires = DateTime.Now.AddYears(50);

    のようにしてみたらどうなりますか?

    JavaScript ではなく .NET 4 の CookieContainer の話ですが、以下のスレッドに書いてあるように有効期限 DateTime.MaxValue の Cookie を無視するということがありました。

    .NET FW3.5 と4.0におけるASP.NET WEBサービス クライアントの
    CookieContainerの挙動の違いについて
    http://social.msdn.microsoft.com/Forums/ja-JP/065a6981-263b-4b2c-90f3-3ea80377a781/net-fw35-40aspnet-web-cookiecontainer

    ハズレだったらスミマセン。

    <追伸>

    URL が間違っていたので訂正しました。

    • 編集済み SurferOnWww 2013年7月24日 2:33 URL の誤記訂正
    2013年7月24日 2:30
  • SurferOnWww様

    返信ありがとうございました。
    参考URL確認いたしました。

    cookieの有効期限をご指摘の通りに修正しましたが、
    問題の解決にはいたりませんでした。

    Cookieの有効期限については、今後の開発に役立てたいと思います。

    2013年7月24日 3:10
  • ハズレだったようですみません。

    自分の開発環境で、下のコードで試してみました(コード中に「WebBrowser による Cookie取得のテスト」とあるのは気にしないでください)。結果、document.cookie で問題なく取得できました。

    当方の環境は Windows Vista Ultimate SP2 + IE9, ASP.NET 4, IIS7, Visual Studio 2010 Pro です。

    どこかやり方が違うのでは?

    ちなみに、応答ヘッダに含まれる Cookie の設定を Fiddler で見ると以下のようになっています。

    Set-Cookie: ASP.NET_SessionId=yqq4f33gmnvckisn4hxe2qlx; path=/; HttpOnly
    Set-Cookie: DateTimeCookie=2013/07/24 13:24:13; path=/
    Set-Cookie: RandomNumber=374235307; path=/
    Set-Cookie: TEST=true; expires=Fri, 31-Dec-9999 23:59:59 GMT; path=/

    スクリプト document.getElementById("div1").innerHTML = allCookies; の結果は以下の通りとなります。(上の値と違うのは気にしないでください。取得したタイミングが違うので)

    TEST=true; DateTimeCookie=2013/07/24 13:28:53; RandomNumber=1517325953

    なお、HttpOnly 属性を持つ Cookie(上の例では ASP.NET_SessionId)はクライアントスクリプトでは取得できません。理由は、IE6 以降でクロスサイトスクリプティング対応のため HttpOnly 属性が追加され、その属性を持つ HTTP Cookie にはクライアントスクリプトからアクセスできなくなっているからだそうです。

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        protected void Page_Load(object sender, EventArgs e)
        {
            HttpCookie myCookie = new HttpCookie("DateTimeCookie");
            myCookie.Value = DateTime.Now.ToString();
            Response.Cookies.Add(myCookie);
    
            myCookie = new HttpCookie("RandomNumber");
            Random rand = new Random();
            myCookie.Value = rand.Next().ToString();
            Response.Cookies.Add(myCookie);
    
            // 2013/7/24 MSDN Forum の検証用に追加
            // http://social.msdn.microsoft.com/Forums/ja-JP/387822b0-010d-451c-82b4-8f9eb3c75ffc/aspnetcookiejavascript
            var cookie = new HttpCookie("TEST");
            cookie.Value = "true";
            cookie.Expires = DateTime.MaxValue;
            this.Response.Cookies.Set(cookie);
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>WebBrowser による Cookie取得のテスト</title>
        <script type="text/javascript">
        //<![CDATA[
            window.onload = function () {
                var allCookies = document.cookie;
                document.getElementById("div1").innerHTML = allCookies;
            }
        //]]>
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <h1>WebBrowser による Cookie 取得のテスト</h1>
            <div id="div1"></div>
        </div>
        </form>
    </body>
    </html>




    • 編集済み SurferOnWww 2013年7月24日 5:03 環境に IE9 追加
    • 回答としてマーク frtakao 2013年7月24日 7:02
    2013年7月24日 4:48
  • SurferOnWww様

    cookieの値を確認したところ
    cookie.HttpOnly = true
    でしたので、明示的にfalse にしたところ、JavaScriptでcookieの値を取得できました。
    XSSが絡むようですので、セキュリティの面は別途考慮いたします
    (このスレッドの範疇ではないと思いますし)。

    >なお、HttpOnly 属性を持つ Cookie(上の例では ASP.NET_SessionId)はクライアントスクリプトでは取得できません。理由は、IE6 以降でクロスサイトスクリプティング対応のため HttpOnly 属性が追加され、その属性を持つ HTTP Cookie にはクライアントスクリプトからアクセスできなくなっているからだそうです

    お陰様で、本スレッドでの目的を達成することができました。
    ありがとうございました。
    これを機会に、cookie周りの知識をブラッシュアップしたいと思います。
    2013年7月24日 5:23
  • > cookieの値を確認したところ
    > cookie.HttpOnly = true
    > でしたので、明示的にfalse にしたところ、JavaScriptでcookieの値を取得できました。

    HttpCookie.HttpOnly プロパティはデフォルトで false です。なので、ご自分で、明確な意思を持って、コードで ture に設定したのだと理解しています。

    であれば、ture に設定する時点で、それがどういう意味を持つのか MSDN ライブラリを一読してください。そうすればすぐ原因は分かるはずです。

    HttpCookie.HttpOnly プロパティ
    http://msdn.microsoft.com/ja-jp/library/system.web.httpcookie.httponly(v=vs.90).aspx

    上の URL のページにも、HttpOnly 属性を持つ Cookie はクライアントスクリプトでは取得できないことは明確に書いてあります。

    また、コードをアップする場合は中途半端に省略しないでください。そうしていただけていたら、最初の質問で cookie.HttpOnly = true というコードが見つかるはずなので、お互い時間のムダが省けます。

    2013年7月24日 6:29