none
Cookieの操作で、サーバーコードとJavascriptの併用について RRS feed

  • 質問

  • いつもお世話になっております。

    今回、Javascriptで作成したCookieがサーバーサイドから指示した場合、無効化できていない(厳密には、無効なCookieを読み込んでしまう)という点で、Cookieの操作について行き詰まってしまい、知恵をお借りしたいのですが、
     
    状況説明からしますと…
    TextBox (Multiline) / html上は textarea
    にて編集中に戻るボタンを押してしまうと、配置しているコントロールの都合で『Web ページの有効期限が切れています』ページになってしまい、そこから元の編集画面に戻ろうとすると、編集画面も『Web ページの有効期限が切れています』になってしまうため、画面が切り替わるときに一時的に編集内容をCookieに入れておくような仕組みを考えました。そして、再度、ページを読み込んだ際に、Cookieがあれば、前回の編集内容を復元するというモノです。

    そして、設計上は問題ないと考えられるのですが、IE9では、期待するような結果が得られませんでした。(FF9では、期待通り。)
     
    (ちなみに、戻るボタンを押させない、もしくは戻るボタンを使わせないようにする良いアイディアがありましたら、併せてご指導いただきたく思います。なお、別窓を呼び出して、Javascriptで戻るボタンを消す以外の方法で何かあればと思います。設計上、別窓は好ましくないのです…。それに、BackSpaceの問題もあるので…)


    流れとしては、
    1.ページを読み込んだときに、クッキーが残っていればクッキーの内容を編集領域に挿入(サーバーサイド)
    2.編集画面から次の確認画面に移るとき、Cookieに編集内容を保存(サーバーサイド)
    3.ページが物理的に移るとき、編集内容をCookieに保存(Javascript)
    4.全ての処理が終わったら、Cookieの内容を消去(サーバーサイド)
    このような機能を備えています


    コードは、
    1.(Page_onloadにて実行/復元ポイント)
    If Not Request.Cookies("TempEditCont") Is Nothing Then
                    Dim tempEditCookie As HttpCookie = Request.Cookies("TempEditCont")
                    txtSubj.Text = HttpUtility.UrlDecode(tempEditCookie("TempSubj").ToString)
                    txtBody.Text = HttpUtility.UrlDecode(tempEditCookie("TempBody").ToString)
                    lblMSG.Text = "このユーザーは、前回書きかけのまま終了し、一時保存文書が残っていますので復帰しました。"
                End If
    

    2.(編集内容確認ボタン実行時にCookieを作成)
    Dim TempEditCookie As New HttpCookie("TempEditCont")
            TempEditCookie.Values("TempSubj") = HttpUtility.UrlEncode(txtSubj.Text)
            TempEditCookie.Values("TempBody") = HttpUtility.UrlEncode(txtBody.Text)
            TempEditCookie.Expires = DateTime.Now.AddDays(3)
            Response.Cookies.Add(TempEditCookie)
    

    3.(編集画面から離脱するときに、強制的にCookieに内容を保存)
    <script language="JavaScript" type="text/javascript">
                            window.onbeforeunload = function () {
                                var myExp = new Date();
                                myExp.setTime(myExp.getTime() + (1 * 24 * 60 * 60 * 1000));
                                var CookieItems = "TempEditCont=TempSubj=" + encodeURI(document.getElementById("txtSubj").value) + "&TempBody=" + encodeURI(document.getElementById("txtBody").value) + ";";
                                var myExpires = "expires=" + myExp.toGMTString();
                                document.cookie = CookieItems + myExpires;
                            }
                        </script>
    

    4.(編集作業終了時に実行)
    If Not Request.Cookies("TempEditCont") Is Nothing Then
                Dim tempEditCookie As HttpCookie = Request.Cookies("TempEditCont")
                tempEditCookie.Expires = DateTime.Now.AddDays(-1D)
                Response.Cookies.Add(tempEditCookie)
            End If
    

    です。
     
    考察結果を羅列しますと、
    A.サーバーサイドのコードのみは期待通り(3.を外したコード)(4.通過後に復元ポイント(1.)を実行してもCookieを読み込まない<-当然の結果)
    B.3.で作成したCookieが入ると、4.を通過しても有効期限が指定通りに変化しない
    C.3.で作成したCookieを含んでいるとき、4.を通過した後、IE9を一度閉じて、再度プログラムを呼び出しましたが、Cookieが残ったままになった
    D.全部の処理が終了したときに、最後に押すボタンコントロールに、
    OnClientClick="javascript:document.cookie = 'TempEditCont=TempSubj=&TempBody=;expires=Thu, 1 Jan 1970 00:00:00 GMT'"
    

    を設定して、4.と同時に(厳密にはクライアントサイドで先に)、JavascriptからもCookieの有効期限を無効にする操作をしているが、続けて復元ポイント(1.)を呼び出すところを実行すると、IE9は無効なCookieを読み込んできてしまい、なおかつ、値が全て空白(最後のJavascriptでCookieに指示した通り)さらに、一度ブラウザを閉じても、Cookieが落ちない。
    E.その他にもいくつか試した実験がありますが、あまり参考にならないと思うので、ひとまずココまでにします。


    要するに、サーバーサイドだけで処理をしていれば問題なく期待通りなのですが、これでは編集画面で戻るボタンなどを押してしまったときに、3.が走っていないので、復元できる機会がものすごく限定的になってしまいます。編集内容確認画面から編集画面へ1つ戻った際に『Web ページの有効期限が切れています』となった場合、編集内容を救えるだけでもだいぶ効果はあるのですが、もう少しイレギュラーが発生した際でも編集内容を救える仕組みを考えています。

    基本的に、Cookieの値の削除タイミングはブラウザ次第だと思うので、そういう仕様だという結論になってしまったらあきらめるしかないのですが、サーバーサイドからの指示では期待通りで、Javascriptから指の示が入ると期待通りにならないという点で引っかかっております。jQueryなどをうまく併用するとうまい解決策などもあるかと思いますが、仕組みをあまり複雑にせず、できる方法をと考えています。

    妙案をご存じの方がいらっしゃいましたら、何卒よろしくお願いします。

    ぷら





    • 編集済み Pla 2012年1月19日 15:44
    2012年1月19日 15:32

回答

  • SurferOnWwwさま
    いつも大変お世話になっております。今回も、テストコードを作ってくださり、また、検証もしていただき、誠にありがとうございます。心より感謝申し上げます。
    実は、検証コードを使っていろいろ実験しているうちに、自己解決してしまいましたので、今後のために、その結果をまとめておきます。
     
    まず、期待通り動かなかった原因は、サーバーコードが作るCookie情報と、Javascriptで作成しているCookie情報が異なったため、2つのCookie情報ができてしまい、最後にサーバーコードでCookieの有効期限を無効にして破棄しているように見えたCookieはあくまでサーバーコードが作ったCookieのみで、Javascriptで作成されたCookieは別物扱いで削除はされず…
    しかしながら、キーは同じなので、ページ再読み込み時にCookieを読み込んできてしまうという現象が起きていました。
    そして、その原因は、
    サーバーコードが作るCookieと、Javascriptが作るCookieの違いは、今回の場合、Path情報が付加されているかどうか?の違いでした。
    IE9の開発者ツールの中に、キャッシュを表示させる機能が付いていて、その中に、Cookieの詳細情報を表示する機能も付いていますが、そこで2重にできていると思われるCookieを比較したところ、Path情報が異なっていて、これのために、別々のCookie扱いで2つのキーが存在してしまったようです。
    以下2つの検証コードで、違いが確認できます。
    Path情報を入れている部分は、書き方としては意味合いが正しくないのですが、わかりやすくするために、あえてこのようにしています。
    Javascript側でPath情報を入れないでこのコードの一連の流れを実行すると、全て完了したときに、2つのキーのCookieが残ります。このとき、目視でわかる情報の中にPath情報が含まれていないので気がつきませんでしたが、Javascript側でPath情報を入れてCookieを作成すると、Cookieのキーが重複せずに1つのCookie情報が作成されます。
    ですので、今回は、Path情報の違いから、2つのCookieが作成されていたので、期待通りの結果が得られなかったという結論に至りました。
    もし、この結論が違うようでしたら、訂正をお願いします。
    お付き合いいただき、誠にありがとうございました。引き続き、今後とも何卒よろしくお願いします。
     
    <%@ Page Language="VB" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        Protected Sub Page_Load(sender As Object, e As System.EventArgs)
            Dim tCookie As HttpCookie = Request.Cookies("EditCont")
            If Not tCookie Is Nothing Then TextBox1.Text = tCookie.Value
        End Sub
        
        Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
            Panel1.Visible = False
            Panel2.Visible = True
        End Sub
    
        Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
            Panel2.Visible = False
            Panel3.Visible = True
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Value = TextBox1.Text
            vCookie.Expires = DateTime.Now.AddDays(3D)
            Response.Cookies.Add(vCookie)
        End Sub
    
        Protected Sub Button3_Click(sender As Object, e As System.EventArgs)
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vCookie)
            Dim vvCookie As HttpCookie = Request.Cookies("EditCont")
            vvCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vvCookie)
            Response.Redirect("cookietest.aspx")
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="初期画面"></asp:Label>
            <asp:Button ID="Button1" runat="server" Text="編集画面へ" onclick="Button1_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        <asp:Panel ID="Panel2" runat="server" Visible="false">
            <asp:Label ID="Label2" runat="server" Text="編集画面"></asp:Label>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button2" runat="server" Text="確認画面へ" onclick="Button2_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
            <script type="text/javascript">
            //<![CDATA[
                    window.onbeforeunload = function () {
                        var myExp = new Date();
                        myExp.setTime(myExp.getTime() + (3 * 24 * 60 * 60 * 1000));
                        var CookieItems = "EditCont=" + document.getElementById("TextBox1").value;
                        var myExpires = "; expires=" + myExp.toGMTString();
                        document.cookie = CookieItems + myExpires;
                    }
            //]]>
            </script>
        </asp:Panel>
        <asp:Panel ID="Panel3" runat="server" Visible="false">
            <asp:Label ID="Label3" runat="server" Text="確認画面"></asp:Label>
            <asp:Label ID="Label4" runat="server" Text=""></asp:Label>
            <asp:Button ID="Button3" runat="server" Text="編集完了" onclick="Button3_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        </form>
    </body>
    </html>
    
    

    <%@ Page Language="VB" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        Protected Sub Page_Load(sender As Object, e As System.EventArgs)
            Dim tCookie As HttpCookie = Request.Cookies("EditCont")
            If Not tCookie Is Nothing Then TextBox1.Text = tCookie.Value
        End Sub
        
        Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
            Panel1.Visible = False
            Panel2.Visible = True
        End Sub
    
        Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
            Panel2.Visible = False
            Panel3.Visible = True
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Value = TextBox1.Text
            vCookie.Expires = DateTime.Now.AddDays(3D)
            Response.Cookies.Add(vCookie)
        End Sub
    
        Protected Sub Button3_Click(sender As Object, e As System.EventArgs)
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vCookie)
            Dim vvCookie As HttpCookie = Request.Cookies("EditCont")
            vvCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vvCookie)
            Response.Redirect("cookietest.aspx")
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="初期画面"></asp:Label>
            <asp:Button ID="Button1" runat="server" Text="編集画面へ" onclick="Button1_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        <asp:Panel ID="Panel2" runat="server" Visible="false">
            <asp:Label ID="Label2" runat="server" Text="編集画面"></asp:Label>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button2" runat="server" Text="確認画面へ" onclick="Button2_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
            <script type="text/javascript">
            //<![CDATA[
                    window.onbeforeunload = function () {
                        var myExp = new Date();
                        myExp.setTime(myExp.getTime() + (3 * 24 * 60 * 60 * 1000));
                        var CookieItems = "EditCont=" + document.getElementById("TextBox1").value;
                        var myExpires = "; path=" + location.pathname + "; expires=" + myExp.toGMTString();
                        document.cookie = CookieItems + myExpires;
                    }
            //]]>
            </script>
        </asp:Panel>
        <asp:Panel ID="Panel3" runat="server" Visible="false">
            <asp:Label ID="Label3" runat="server" Text="確認画面"></asp:Label>
            <asp:Label ID="Label4" runat="server" Text=""></asp:Label>
            <asp:Button ID="Button3" runat="server" Text="編集完了" onclick="Button3_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        </form>
    </body>
    </html>
    
    

    ぷら

    • 編集済み Pla 2012年1月20日 19:52
    • 回答としてマーク Pla 2012年1月23日 4:03
    2012年1月20日 19:46
  • > 今回は、Path情報の違いから、2つのCookieが作成されていたので、
    > 期待通りの結果が得られなかったという結論に至りました。

    そのようですね。

    (1) document.cookie で path を省略してあるので、パスはそのページの
    ディレクトリになる。

    (2) 一方、HttpCookie.Path を設定してないのでサーバーから送られる応
    答ヘッダーの Set-Cookie: に含まれるパス設定は path=/ になる。

    上の (1) の Cookie を書き換えまたは削除するため、上の (2) で同名の
    クッキーをブラウザに送っても、パスが違うので上書きされず、両方のク
    ッキーが保存されたということですね。

    先にアップしたコードで自分が検証したときは、サイト直下にページを置
    いていたので、両方 path=/ になって問題に気がつきませんでした。

     

    • 回答としてマーク Pla 2012年1月23日 4:03
    2012年1月21日 9:25

すべての返信

  • 詳しくは見てないのでハズレかもしれませんが、javascriptのブラウザ依存性の問題ではないのですか?

    なぜsessionをつかわないのですか(?

    2012年1月19日 23:44
  • 問題は、4 の「編集作業終了時」にサーバーの応答ヘッダーの Set-Cookie: の
    expires= に過去の日時を設定しても、その次の要求の時当該 Cookie が削除さ
    れないということですよね。

    その部分を検証するため、最小限のコードを書いて試してみましたが、そんな
    ことはなくて、IE9 でも FF9 でも期待通り動きました。

    何かの間違いではないのですか?

    検証に使ったコードをアップしておきますので、試してみてください。

    アップしたコードの中の 129-OnBeforeUnload(1).aspx というのは検証に使っ
    たページのファイル名です。

    <%@ 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 Button1_Click(object sender, EventArgs e)
        {
            HttpCookie tempEditCookie = Request.Cookies["TempEditCont"];
            tempEditCookie.Expires = DateTime.Now.AddDays(-1D);
            Response.Cookies.Add(tempEditCookie);
            Response.Redirect("~/129-OnBeforeUnload(1).aspx");
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            HttpCookie tempEditCookie = Request.Cookies["TempEditCont"];
            if (tempEditCookie != null)
            {
                Label1.Text = Server.HtmlEncode(tempEditCookie.Value);
            }
            else
            {
                Label1.Text = "cookie は空です。";
            }
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>編集のページ</title>
        <script type="text/javascript">
        //<![CDATA[
            window.onbeforeunload = function () {
                var myExp = new Date();
                myExp.setTime(myExp.getTime() + (1 * 24 * 60 * 60 * 1000));
                var CookieItems = "TempEditCont=This is cookie set at Client side;";
                var myExpires = "expires=" + myExp.toGMTString();
                document.cookie = CookieItems + myExpires;
            }
        //]]>
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Label ID="Label1" runat="server"></asp:Label>
            <br />
            <asp:Button ID="Button1" 
                runat="server" 
                Text="編集完了" 
                OnClick="Button1_Click" />
            <br />
            <asp:HyperLink ID="HyperLink1" 
                runat="server" 
                NavigateUrl="~/129-OnBeforeUnload(1).aspx">
                HyperLink
            </asp:HyperLink>
        </div>
        </form>
    </body>
    </html>
    
    

    2012年1月20日 15:04
  • SurferOnWwwさま
    いつも大変お世話になっております。今回も、テストコードを作ってくださり、また、検証もしていただき、誠にありがとうございます。心より感謝申し上げます。
    実は、検証コードを使っていろいろ実験しているうちに、自己解決してしまいましたので、今後のために、その結果をまとめておきます。
     
    まず、期待通り動かなかった原因は、サーバーコードが作るCookie情報と、Javascriptで作成しているCookie情報が異なったため、2つのCookie情報ができてしまい、最後にサーバーコードでCookieの有効期限を無効にして破棄しているように見えたCookieはあくまでサーバーコードが作ったCookieのみで、Javascriptで作成されたCookieは別物扱いで削除はされず…
    しかしながら、キーは同じなので、ページ再読み込み時にCookieを読み込んできてしまうという現象が起きていました。
    そして、その原因は、
    サーバーコードが作るCookieと、Javascriptが作るCookieの違いは、今回の場合、Path情報が付加されているかどうか?の違いでした。
    IE9の開発者ツールの中に、キャッシュを表示させる機能が付いていて、その中に、Cookieの詳細情報を表示する機能も付いていますが、そこで2重にできていると思われるCookieを比較したところ、Path情報が異なっていて、これのために、別々のCookie扱いで2つのキーが存在してしまったようです。
    以下2つの検証コードで、違いが確認できます。
    Path情報を入れている部分は、書き方としては意味合いが正しくないのですが、わかりやすくするために、あえてこのようにしています。
    Javascript側でPath情報を入れないでこのコードの一連の流れを実行すると、全て完了したときに、2つのキーのCookieが残ります。このとき、目視でわかる情報の中にPath情報が含まれていないので気がつきませんでしたが、Javascript側でPath情報を入れてCookieを作成すると、Cookieのキーが重複せずに1つのCookie情報が作成されます。
    ですので、今回は、Path情報の違いから、2つのCookieが作成されていたので、期待通りの結果が得られなかったという結論に至りました。
    もし、この結論が違うようでしたら、訂正をお願いします。
    お付き合いいただき、誠にありがとうございました。引き続き、今後とも何卒よろしくお願いします。
     
    <%@ Page Language="VB" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        Protected Sub Page_Load(sender As Object, e As System.EventArgs)
            Dim tCookie As HttpCookie = Request.Cookies("EditCont")
            If Not tCookie Is Nothing Then TextBox1.Text = tCookie.Value
        End Sub
        
        Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
            Panel1.Visible = False
            Panel2.Visible = True
        End Sub
    
        Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
            Panel2.Visible = False
            Panel3.Visible = True
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Value = TextBox1.Text
            vCookie.Expires = DateTime.Now.AddDays(3D)
            Response.Cookies.Add(vCookie)
        End Sub
    
        Protected Sub Button3_Click(sender As Object, e As System.EventArgs)
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vCookie)
            Dim vvCookie As HttpCookie = Request.Cookies("EditCont")
            vvCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vvCookie)
            Response.Redirect("cookietest.aspx")
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="初期画面"></asp:Label>
            <asp:Button ID="Button1" runat="server" Text="編集画面へ" onclick="Button1_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        <asp:Panel ID="Panel2" runat="server" Visible="false">
            <asp:Label ID="Label2" runat="server" Text="編集画面"></asp:Label>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button2" runat="server" Text="確認画面へ" onclick="Button2_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
            <script type="text/javascript">
            //<![CDATA[
                    window.onbeforeunload = function () {
                        var myExp = new Date();
                        myExp.setTime(myExp.getTime() + (3 * 24 * 60 * 60 * 1000));
                        var CookieItems = "EditCont=" + document.getElementById("TextBox1").value;
                        var myExpires = "; expires=" + myExp.toGMTString();
                        document.cookie = CookieItems + myExpires;
                    }
            //]]>
            </script>
        </asp:Panel>
        <asp:Panel ID="Panel3" runat="server" Visible="false">
            <asp:Label ID="Label3" runat="server" Text="確認画面"></asp:Label>
            <asp:Label ID="Label4" runat="server" Text=""></asp:Label>
            <asp:Button ID="Button3" runat="server" Text="編集完了" onclick="Button3_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        </form>
    </body>
    </html>
    
    

    <%@ Page Language="VB" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        Protected Sub Page_Load(sender As Object, e As System.EventArgs)
            Dim tCookie As HttpCookie = Request.Cookies("EditCont")
            If Not tCookie Is Nothing Then TextBox1.Text = tCookie.Value
        End Sub
        
        Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
            Panel1.Visible = False
            Panel2.Visible = True
        End Sub
    
        Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
            Panel2.Visible = False
            Panel3.Visible = True
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Value = TextBox1.Text
            vCookie.Expires = DateTime.Now.AddDays(3D)
            Response.Cookies.Add(vCookie)
        End Sub
    
        Protected Sub Button3_Click(sender As Object, e As System.EventArgs)
            Dim vCookie As HttpCookie = Request.Cookies("EditCont")
            vCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vCookie)
            Dim vvCookie As HttpCookie = Request.Cookies("EditCont")
            vvCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vvCookie)
            Response.Redirect("cookietest.aspx")
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="初期画面"></asp:Label>
            <asp:Button ID="Button1" runat="server" Text="編集画面へ" onclick="Button1_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        <asp:Panel ID="Panel2" runat="server" Visible="false">
            <asp:Label ID="Label2" runat="server" Text="編集画面"></asp:Label>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button2" runat="server" Text="確認画面へ" onclick="Button2_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
            <script type="text/javascript">
            //<![CDATA[
                    window.onbeforeunload = function () {
                        var myExp = new Date();
                        myExp.setTime(myExp.getTime() + (3 * 24 * 60 * 60 * 1000));
                        var CookieItems = "EditCont=" + document.getElementById("TextBox1").value;
                        var myExpires = "; path=" + location.pathname + "; expires=" + myExp.toGMTString();
                        document.cookie = CookieItems + myExpires;
                    }
            //]]>
            </script>
        </asp:Panel>
        <asp:Panel ID="Panel3" runat="server" Visible="false">
            <asp:Label ID="Label3" runat="server" Text="確認画面"></asp:Label>
            <asp:Label ID="Label4" runat="server" Text=""></asp:Label>
            <asp:Button ID="Button3" runat="server" Text="編集完了" onclick="Button3_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        </form>
    </body>
    </html>
    
    

    ぷら

    • 編集済み Pla 2012年1月20日 19:52
    • 回答としてマーク Pla 2012年1月23日 4:03
    2012年1月20日 19:46
  • > 今回は、Path情報の違いから、2つのCookieが作成されていたので、
    > 期待通りの結果が得られなかったという結論に至りました。

    そのようですね。

    (1) document.cookie で path を省略してあるので、パスはそのページの
    ディレクトリになる。

    (2) 一方、HttpCookie.Path を設定してないのでサーバーから送られる応
    答ヘッダーの Set-Cookie: に含まれるパス設定は path=/ になる。

    上の (1) の Cookie を書き換えまたは削除するため、上の (2) で同名の
    クッキーをブラウザに送っても、パスが違うので上書きされず、両方のク
    ッキーが保存されたということですね。

    先にアップしたコードで自分が検証したときは、サイト直下にページを置
    いていたので、両方 path=/ になって問題に気がつきませんでした。

     

    • 回答としてマーク Pla 2012年1月23日 4:03
    2012年1月21日 9:25
  • 一つ質問するのを忘れてました。

    > IE9では、期待するような結果が得られませんでした。(FF9では、期待通り。)

    同名でもパスが違うと上書きされないのは IE9 でも FF9 でも(たぶん、他のメ
    ジャーなブラウザでも)同じはずですが、上記の理由は何だったのでしょうか?

    2012年1月22日 1:09
  • テスト用サンプルコードも一部完全ではなかったので、最終的なコードを掲載します。

    具体的には、html内に埋め込んだJavascriptのパス情報を変えています

    ";path=/; expires="

     

    <%@ Page Language="VB" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
    
        Protected Sub Page_Load(sender As Object, e As System.EventArgs)
            Dim tCookie As HttpCookie = Request.Cookies("EditCont")
            If Not tCookie Is Nothing Then TextBox1.Text = tCookie.Value
        End Sub
        
        Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
            Panel1.Visible = False
            Panel2.Visible = True
        End Sub
    
        Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
            Panel2.Visible = False
            Panel3.Visible = True
            Dim vCookie As HttpCookie = Response.Cookies("EditCont")
            vCookie.Value = TextBox1.Text
            vCookie.Expires = DateTime.Now.AddDays(3D)
            Response.Cookies.Add(vCookie)
        End Sub
    
        Protected Sub Button3_Click(sender As Object, e As System.EventArgs)
            Dim vCookie As HttpCookie = Response.Cookies("EditCont")
            vCookie.Expires = DateTime.Now.AddDays(-1D)
            Response.Cookies.Add(vCookie)
            TextBox1.Text = ""
            Response.Redirect("cookietest.aspx")
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="初期画面"></asp:Label>
            <asp:Button ID="Button1" runat="server" Text="編集画面へ" onclick="Button1_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
        </asp:Panel>
        <asp:Panel ID="Panel2" runat="server" Visible="false">
            <asp:Label ID="Label2" runat="server" Text="編集画面"></asp:Label>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button2" runat="server" Text="確認画面へ" onclick="Button2_Click" />
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
            <script type="text/javascript">
            //<![CDATA[
                window.onbeforeunload = function() {
                    var myExp = new Date();
                    myExp.setTime(myExp.getTime() + (3 * 24 * 60 * 60 * 1000));
                    var CookieItems = "EditCont=" + document.getElementById("TextBox1").value;
                    var myExpires = ";path=/; expires=" + myExp.toGMTString();
                    document.cookie = CookieItems + myExpires;
                };
            //]]>
            </script>
        </asp:Panel>
        <asp:Panel ID="Panel3" runat="server" Visible="false">
            <asp:Label ID="Label3" runat="server" Text="確認画面"></asp:Label>
            <asp:Label ID="Label4" runat="server" Text=""></asp:Label>
            <asp:Button ID="Button3" runat="server" Text="編集完了" onclick="Button3_Click" />
            <a href="javascript:void(0);" onclick="delcookie();">クッキー削除</a>
            <a href="javascript:void(0);" onclick="alert(document.cookie)">クッキー確認</a>
            <script type="text/javascript">
                //<![CDATA[
                function delcookie() {
                    document.cookie = "EditCont=;path=/;expires=Thu, 1 Jan 1970 00:00:00 GMT";
                };
                //]]>
            </script>
        </asp:Panel>
        </form>
    </body>
    </html>
    
    


    ぷら
    2012年1月23日 4:03
  • SurferOnWwwさま

    お世話になっております。お力添えいただき、誠にありがとうございました。心より感謝申し上げます。

    なお、検証実験時に、FF9で期待通りとなった理由についてはよくわかりません。結果を見たらそういうことになっていたと記録しているのですが、恐らく検証したときのコードに何か想定外のことが起こっていたか、Cookieの確認コードが違っていたか!?意図しない何らかの理由があったのだと思います。

     

     

    確実に検証できるコードを再掲していますので、このスレッドの問題に当たった方が参考にいただく際は、そちらを参照ください。


    ぷら
    2012年1月23日 4:10