トップ回答者
ASP.NETでセットしたCookieをJavaScriptで参照する

質問
-
開発環境
・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
回答
-
ハズレだったようですみません。
自分の開発環境で、下のコードで試してみました(コード中に「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
すべての返信
-
検証してませんが・・・
試しに、
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 の誤記訂正
-
ハズレだったようですみません。
自分の開発環境で、下のコードで試してみました(コード中に「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
-
SurferOnWww様
cookieの値を確認したところ
cookie.HttpOnly = true
でしたので、明示的にfalse にしたところ、JavaScriptでcookieの値を取得できました。
XSSが絡むようですので、セキュリティの面は別途考慮いたします
(このスレッドの範疇ではないと思いますし)。
>なお、HttpOnly 属性を持つ Cookie(上の例では ASP.NET_SessionId)はクライアントスクリプトでは取得できません。理由は、IE6 以降でクロスサイトスクリプティング対応のため HttpOnly 属性が追加され、その属性を持つ HTTP Cookie にはクライアントスクリプトからアクセスできなくなっているからだそうです
お陰様で、本スレッドでの目的を達成することができました。
ありがとうございました。
これを機会に、cookie周りの知識をブラッシュアップしたいと思います。 -
> 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 というコードが見つかるはずなので、お互い時間のムダが省けます。