2010-12-30 3 views
0

У меня было следующее:Вызов сервлет после функции яваскрипта убивает сеанс

<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-функции, тогда действительно может возникнуть условие гонки. Это не выполняется синхронно. Он выполняет «в фоновом режиме».

Вы должны убедиться, что ссылка вызывается только при завершении асинхронного запроса. Предполагая, что вы делаете это в «простой ваниль» JS XMLHttpRequest вместо удобной Ajaxical JS-библиотеки, такой как jQuery, вам необходимо выполнить эту работу в 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

Привет, спасибо за ответы и разъяснения. Я понимаю все в вашем примере кода, за исключением последних трех строк. Я заменил бы http: // example.com своим URL-адресом сервлета? – Keefu

+0

Тот же URL-адрес, что и асинхронно вызывается внутри вашей функции. Вы не отображали весь элемент функции CreatePageView(), поэтому я просто привел пример. Или вы не запускаете асинхронный запрос в своей функции вообще? – BalusC

+0

Проблема заключается в том, что функция javascript, которую я вызываю, является сторонней библиотекой, используемой для веб-аналитики (фиксируя количество кликов по ссылке), поэтому я не уверен, что она запускает асинхронный запрос или нет. Из-за ситуации в гонке, я бы предположил, что это асинхронный запрос. Могу ли я использовать этот метод для вызова функции с помощью xhr.open()? – Keefu

Смежные вопросы