JSNI - $wnd.location.assign() не запускается сразу

У меня есть следующий код JSNI в моем приложении GWT, который делает HTTP-запрос для обнаружения перенаправления URL -

private native void checkSession(String url)
    /*-{
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(e) {
                if (xhr.readyState == 4) {
                    if (url != xhr.responseURL) {
                        $wnd.alert("Your session has timed out.");
                        $wnd.location.assign(url);
                    }
                }
            }
            xhr.open("GET", url, true);
            xhr.send();
    }-*/;

Если запрошенный URL-адрес не совпадает с URL-адресом ответа, сеанс считается истекшим; на котором я хочу отобразить окно предупреждения, сообщающее пользователю, что время сеанса истекло, и инициировать перенаправление, когда они нажимают кнопку ОК.

У меня есть собственный класс, который реализует AsyncCallback, Используя эту технику, я смог обеспечить onFailure() звонить checkSession() всякий раз, когда StatusCodeException происходит.

Проблема в том, что всплывающее окно всплывает несколько раз, прежде чем $wnd.location.assign(url) может инициировать перенаправление. Я понимаю, что несколько onFailure() здесь выполняются методы, в результате чего оповещение появляется несколько раз, но мой вопрос: почему $wnd.location.assign(url) не выполняется до последнего onFailure() метод выполняется, пока $wnd.alert() что прямо над ним, выполняется каждый раз?

Как я могу принудительно перенаправить в этой ситуации? В идеале, я хочу, чтобы оповещение всплыло один раз и перенаправлялось сразу после нажатия кнопки ОК.

1 ответ

Решение

Согласно этому ответу, браузер будет пытаться выполнить оставшийся код JavaScript, пока страница не будет перенаправлена; который объясняет появление нескольких предупреждений перед перенаправлением страницы.

Чтобы обойти это, я объявил private static boolean redirect = false;, Когда в коде JSNI обнаруживается перенаправление URL, я проверяю, redirect является falseи, если это так, я отображаю предупреждение и устанавливаю redirect = true -

if (@fully.qualified.name::redirect == false) {
       @fully.qualified.name::redirect = true;
       $wnd.alert("Your session has timed out.");
}
$wnd.location.assign(url);

Таким образом, я смог показать предупреждение только один раз, прежде чем начать перенаправление.

Другие вопросы по тегам