В javascript, как я могу однозначно идентифицировать одно окно браузера из другого, которые находятся под тем же идентификатором сессии - PullRequest
28 голосов
/ 14 мая 2009

Пользователи моего веб-приложения могут иметь более одного открытого окна браузера и указывать на одну и ту же страницу. Я бы хотел, чтобы состояние некоторых вещей на странице (загружаемых через ajax) сохранялось при обратной передаче. Я могу хранить файлы cookie или на моем сервере. В любом случае, я не могу понять, как я могу различить каждое окно.

Например, скажем, у пользователя Боба есть два окна браузера, открытых на странице ListOfSomething. Каждый список имеет атрибут LoadedPageNumber , который мне нужно сохранить. В противном случае пользователи всегда оказываются на странице 1 при обновлении. Боб мог загрузить окно браузера 1 и указать его на странице 5, а затем загрузить окно 2 браузера и указать его на странице 14. Если я просто сохраню атрибут на основе идентификатора сеанса, Боб получит страницу 14 в окне 1, если обновит его.

Обратите внимание, что мои переменные состояния на самом деле намного сложнее, чем этот простой пример, и моя неспособность сохранить их может привести к большим проблемам (недостаткам в моем приложении).

Мне нужен какой-то идентификатор окна браузера или что-то в этом роде. Конечно, это должно быть кросс-браузерное решение (IE6 +, Wekbit? +, FF2 +)

Есть идеи?

Примечание об актуальности: имейте в виду, что это полезно и в случае, когда вы смешиваете старые страницы на основе форм с новыми элементами с поддержкой AJAX. Иногда вам нужно отправить обратно формы, и вы не хотите терять некоторые значения состояния на стороне клиента.

Ответы [ 5 ]

37 голосов
/ 14 мая 2009

вы могли бы установить свое собственное имя окна, точный синтаксис сейчас мне ускользает, но вы можете использовать текущее время и идентификатор сессии, чтобы создать уникальный идентификатор при загрузке окна, а затем использовать этот идентификатор

Это будет сделано так же, как вы устанавливаете имя в функции javascript window.open (), (но вы можете сделать это самостоятельно, вместо нового окна)

Google показывает:

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

UPDATE

Что касается необходимости сохранить это из обновления в обновление, я провел несколько тестов, и похоже, чтобы сохранить его из обновления в обновление. Используя Firefox 3, при начальной загрузке имя окна остается пустым, и нажимая CTRL + R снова и снова, и имя окна заполняется. Затем я прокомментировал настройку кода имени и перезагрузил, и он все еще сохранил имя.

<script type="text/javascript">

    alert( self.window.name );

    self.window.name = "blah";

</script>

UPDATE

Я должен обратить внимание на комментарий ниже о плагине jQuery 'jquery-session', который действительно работает и предлагает намного больше, чем то, что обсуждалось здесь.

Хотя , следует также четко указать, что он опирается на веб-хранилище HTML5, не поддерживается старыми версиями 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 здесь (для которой я предложил некоторую очистку кода).

1 голос
/ 29 февраля 2016

Это давно, но ответ Роя Рико помог мне сегодня, поэтому я хочу поделиться своим опытом. Чтобы обработать обновление страницы и использование кнопки страницы, я делаю это так:

  • Ваш сервер проверяет, отправляет ли браузер 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>

Надеюсь, что кому-то поможет

Кстати, эту технику следует использовать только на «НЕ СТРАНИЦАХ SEO» из-за необходимости JavaScript для получения контента. Но в целом страницы SEO не нуждаются в идентификации сеанса вкладок.

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

1 голос
/ 14 мая 2009

Как насчет того, чтобы ваш сервер генерировал случайный идентификатор и сохранял его на странице (некоторая переменная javascript), когда он обслуживается? Затем просто включите этот идентификатор в запрос ajax. Это не поможет при обновлении браузера, но до тех пор, пока пользователь оставляет эту страницу на месте (и просто позволяет ajax-компонентам делать свое дело), ​​она должна работать нормально.

0 голосов
/ 13 апреля 2018

window.name может быть перезаписано пользовательскими библиотеками javascript, датчиками времени и т. Д.

Вместо window.name я предлагаю вам использовать метатег DOM head для хранения вашего идентификатора

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

После загрузки страницы вы должны загрузить все через ajax в этом окне, затем вы можете прикрепить этот идентификатор к каждому запросу в качестве значения заголовка (или данных). Например в 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");

Если вы храните информацию о подкачке, сортировке, фильтрации и т. Д. На стороне сервера в качестве атрибута сеанса, их следует хранить отдельно, прикрепляя их к отдельным идентификаторам окон.

0 голосов
/ 16 февраля 2017

Вы можете использовать хранилище сеансов HTML5, просто сгенерировать уникальный идентификатор и установить его в хранилище сеансов! Что хорошего в том, что каждое окно или вкладка имеет свое собственное хранилище сеансов. например:

если мы запустим в 3 окнах следующее:

окно 1: sessionStorage.setItem('key' , 'window1');

окно 2: sessionStorage.setItem('key' , 'window2');

окно 3: sessionStorage.setItem('key' , 'window3');

sessionStorage.getItem('key' ); <<< это вернет соответствующее значение в окне! </p>

окно 1: sessionStorage.getItem('key' ); возвращает окно 1

окно 2: sessionStorage.getItem('key' ); возвращает окно 2

окно 3: sessionStorage.getItem('key'); возвращает окно 3

Я полагаю, что вы пытаетесь сохранить переменную (отдельно для каждой вкладки / окна).

sessionStorage работает как шарм.

Единственная проблема, с которой вы можете столкнуться - браузер должен поддерживать HTML 5.

...