2010-12-30 7 views
0

を殺した後、私は次のように持っていた:呼び出すサーブレットjavascript関数は、セッション

<a href="/servlet/MyServlet" onclick="javascript:CreatePageView();"> Link 1 </a> 

が、私はすべての時間を実行されませんでしたし、レースの状況を作成していたJavaScript関数のCreatePageView()ことに気づきました。ときどきjavascriptが実行され、リダイレクトが最初に起こった時もあります。

私はイベントの順序を制御したいと思って、私のjavascript関数内でサーブレットを呼び出すと思っていました。

function CreatePageView() 
{ 
    //Execute javascript function here 

    //Invoke servlet here 
    document.forms[0].action = "/servlet/MyServlet"; 
    document.forms[0].submit(); 
} 

サーブレットを呼び出すと、セッションが破壊され、ログインページにリダイレクトされます。なぜこれが起こっているのか誰も説明できますか?あるいは、セッションを強制終了せずにサーブレットを呼び出す別の方法を提案してください。前もって感謝します。

答えて

2

JavaScriptがの非同期リクエストを発射しているような感じです。さもなければ問題は意味をなさない。リンクのアクションは、JavaScript関数が返ったときにのみ実行されます。しかし、あなたがJS関数で非同期/ ajaxical要求を発射しているときは、本当に競合状態が発生する可能性があります。つまり、同期して実行されません。それは "バックグラウンドで"実行されます。

非同期要求が完了したときにのみリンクが呼び出されるようにする必要があります。 jQueryのような便利なAjaxical JSライブラリではなく、XMLHttpRequestによって "プレーンバニラ" JSでそれをやっているとすれば、onreadystatechangeで仕事をする必要があります。

変更リンクを次のように

<a href="/servlets/MyServlet" onclick="return createPageView(this)"> 

javascript: pseudoprotocolが不要であり、それが機能は通常小文字で始まるJSことに注意してください)

そして、次のようにあなたのJS関数を修正しました。( MSIE互換ではなく、自分で修正してください)

function createPageView(link) { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      window.location = link.href; // See? 
     } 
    } 
    xhr.open('GET', 'http://example.com', true); 
    xhr.send(null); 
    return false; // Block link's default action. 
} 

セッションが破棄される理由については、要求ヘッダーに適切なセッションCookieが含まれていない場合、またはサーバー側でsession.invalidate()を呼び出す場合、または要求が実行されたときに破棄されます別のドメイン/コンテキストでどちらが犯人であるかを調査できるのはあなただけです。

+0

こんにちは、感謝して物事を明確化してくれてありがとうございます。最後の3行を除いて、コード例のすべてを理解しています。 http:// example.comをサーブレットのURLに置き換えることはできますか? – Keefu

+0

関数内で非同期に呼び出されたのと同じURLです。 'CreatePageView()'関数の本文全体を表示していないので、例を示しました。あるいは、あなたの関数で非同期要求をまったく実行していませんか? – BalusC

+0

問題は、私が呼び出すjavascript関数が、Web解析(リンクがクリックされた回数をキャプチャする)に使用されるサードパーティライブラリであるため、非同期要求を出しているかどうかわかりません。競争状況のために、私はそれが非同期要求であると思います。このメソッドをxhr.open()を使って関数を呼び出すために使用することはできますか? – Keefu

関連する問題