web-dev-qa-db-ja.com

JavaScriptでは、同じcookiedベースのセッションIDの下にある別のブラウザウィンドウをどのように一意に識別することができますか

私のWebアプリケーションのユーザーが複数のブラウザーウィンドウを開いて、同じページをポイントしている可能性があります。ページ内の特定の状態(ajax経由でロードされた)の状態をポストバック間で保持したい。クッキーまたはサーバーに保存できます。どちらにしても、それぞれのウィンドウをどのように区別できるのか、考えられません。

たとえば、ユーザーBobが2つのブラウザウィンドウを開いて、ListOfSomethingページを開いているとします。各リストには、永続化する必要があるLoadedPageNumber属性があります。それ以外の場合、ユーザーは更新時に常に1ページ目に到達します。 Bobはブラウザウィンドウ1をロードして5ページをポイントし、次にブラウザウィンドウ2をロードして14ページをポイントした可能性があります。セッションIDに基づいて属性を保存するだけの場合、ボブはウィンドウ1を更新すると14ページがウィンドウ1に表示されます。

状態変数は実際にはこの単純な例よりもはるかに複雑であり、それらを永続化できないと大きな問題(アプリの弱点)につながる可能性があることに注意してください。

なんらかのブラウザウィンドウIDなどが必要です。もちろん、クロスブラウザソリューションである必要があります(IE6 +、Wekbit?+、FF2 +)

何か案は?

関連性に関する注意:これは、古いフォームベースのページを新しいAJAXが有効なアイテムと混合している場合にも役立ちます。フォームをポストバックする必要があり、一部のクライアント側の状態値を失いたい。

28
srmark

あなたはあなた自身のウィンドウ名を設定することができます、正確な構文は今私をエスケープします、しかしあなたは現在の時間とセッションIDを使ってウィンドウのロード時にユニークなIDを作成し、そしてそのIDを使うことができます

これは、javascript window.open()関数で名前を設定するのと同じ方法で行われます(ただし、新しいウィンドウではなく、自分自身に名前を付けることができます)。

グーグルショー:

self.window.name = myclass.getUniqueWindowId(thisSession);

更新

これをリフレッシュからリフレッシュまで保存する必要性に関して、私はいくつかのテストを行いましたが、リフレッシュからリフレッシュまで保存するように見えます。 Firefox 3を使用すると、初期ロード時にウィンドウ名が空白になり、CTRL + Rを繰り返し押すと、ウィンドウ名が入力されました。次に、名前コードの設定をコメント化してリロードしましたが、まだ名前が保持されていました。

<script type="text/javascript">

    alert( self.window.name );

    self.window.name = "blah";

</script>

更新

JQueryの 'jquery-session'プラグインに関する以下のコメントに注意してください。これは実際に機能し、ここで説明するものよりもはるかに優れています。

ですが、HTML5のWebストレージに依存していることも明確にする必要があります古いIEバージョン。

企業は依然としてIE 7(ここブラジルでは「以下」)に大きく依存しています。

に基づく self.window.name、HTML5に準拠していないすべてのものに対するソリューションです。クロスブラウザソリューションとして次のコードスニペットを提供します。

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script language="javascript" type="text/jscript">
    //----------------------------------------------------------------------
    //-- guarantees that window.name is a GUID, and that it would
    //-- be preserved whilst this window's life cicle
    //----------------------------------------------------------------------
    //-- window.name will be set to "GUID-<SOME_RANDOM_GUID>"
    //----------------------------------------------------------------------

    $(window).load(
        function () {
            //----------------------
            var GUID = function () {
                //------------------
                var S4 = function () {
                    return(
                            Math.floor(
                                    Math.random() * 0x10000 /* 65536 */
                                ).toString(16)
                        );
                };
                //------------------

                return (
                        S4() + S4() + "-" +
                        S4() + "-" +
                        S4() + "-" +
                        S4() + "-" +
                        S4() + S4() + S4()
                    );
            };
            //----------------------

            if (!window.name.match(/^GUID-/)) {
                window.name = "GUID-" + GUID();
            }
        }
    ) //--------------------------------------------------------------------
</script>

GUID function here を見つけました(コードのクリーンアップを提案しました))。

37
Roy Rico

ずいぶん前のことですが、今日はロイリコの答えが役立ったので、私の体験を共有したいと思います。ページの更新とページの戻るボタンの使用を処理するには、次のようにします。

  • サーバーは、ブラウザがGUIDをリクエストとともに送信するかどうかを確認します(ajaxまたはフォーム送信でのみ機能します)
  • そこにない場合(ブラウザの更新、戻るボタン)、小さなJavaScriptスクリプトを使用してページを送り返すだけです。このスクリプトは、GUIDを作成し、上記のようにwindow.nameストレージに配置します。その後、GUIDを非表示フィールドとして持つフォームを作成し、これをサーバーに送信します。action属性は以前と同じURL(window.location.href)を使用します

->これでサーバーはGUIDを認識し、必要に応じてコンテンツを配信できます。

これが私のコードです(GUIDセキュリティ上の理由でサーバー上に作成します。構文 "$ {gUid}はfreemarkerからのものであり、サーバーからGuidを挿入するだけです):

<script>
    $(window).load(
        function () {
            if (!window.name.match(/^GUID-/)) {
                window.name = "GUID-" + "${gUid}";
            }
            $('<form action='+window.location.href+' method="POST"><input type="hidden" name="X-GUID" id="X-GUID" value='+window.name+'></form>').appendTo('body').submit();
        }
    );  
</script>

誰かを助けることを願っています

ちなみに、コンテンツを取得するにはJavaScriptが必要なため、この手法は「非SEOページ」でのみ使用してください。ただし、一般的に、SEOページはタブセッションを識別する必要はありません。

もちろん、現在はHTML5セッションストレージを利用できますが、古いブラウザが適切に機能する必要があるため、これに依存したくありません。

1
GobiRan

サーバーにランダムにIDを生成させ、それが提供されたときにそのIDをページ(一部のJavaScript変数)に保存させるとどうでしょうか?次に、そのIDをajaxリクエストに含めます。ブラウザーの更新には役立ちませんが、ユーザーがそのページをそのままにしておけば(そしてajaxにその機能を任せるだけで)、問題なく動作するはずです。

1
Herms

window.nameは、カスタムJavaScriptライブラリ、datetimepickersなどで上書きできます。

Window.nameの代わりに、DOMヘッドメタタグを使用してIDを保存することをお勧めします

<html><head><meta id="windowID" content="{YOUR ID}">

ページがロードされたら、そのウィンドウでajaxを介してすべてをロードする必要があります。その後、このIDをすべてのリクエストにヘッダー(またはデータ)値として添付できます。たとえば、次のコードを使用したJQueryでは:

$(document)
    .ajaxSend(function(event, jqXHR, ajaxOptions) {
        jqXHR.setRequestHeader('windowID',
            document.getElementById('windowID').content);
})

このソリューションを使用するには、サーバー側でカスタムヘッダー値にアクセスできる必要があります。たとえば、Javaサーブレットの場合:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String windowName = request.getHeader("windowID");

ページング、ソート、フィルタリングなどの情報をセッション属性としてサーバー側に保存する場合は、それらを個別のウィンドウIDに関連付けて個別に保存する必要があります。

0
Attila

HTML5セッションストレージを使用できます。一意のIDを生成して、セッションストレージに設定するだけです。各ウィンドウまたはタブに独自のセッションストレージがあることのクールな点。例えば ​​:

3つのウィンドウで次のコマンドを実行した場合:

ウィンドウ1:sessionStorage.setItem('key' , 'window1');

ウィンドウ2:sessionStorage.setItem('key' , 'window2');

ウィンドウ3:sessionStorage.setItem('key' , 'window3');

sessionStorage.getItem('key' ); <<<これは、ウィンドウに対応する値を返します!

ウィンドウ1:sessionStorage.getItem('key' );はウィンドウ1を返します

ウィンドウ2:sessionStorage.getItem('key' );はウィンドウ2を返します

ウィンドウ3:sessionStorage.getItem('key');はウィンドウ3を返します

変数を保存しようとしていると思います(各タブ/ウィンドウに個別に)。

sessionStorageはチャームとして機能します。

ブラウザーが直面する可能性がある唯一の問題は、HTML 5をサポートすることです。

0