Webspire

Administrační systém

Jak implementovat transparentní chování aplikace ve více tabech prohlížeče

Dlouhou dobu nás trápil uživatelsky nepříjemný problém s našim administračním systémem Webspire - nekonzistence při práci ve více tabech nebo oknech jednoho prohlížeče. Nakonec se však podařilo najít řešení, které všechny tyto problémy vyřešilo.

Hlavní problém byl v zapamatování si posledních navštívených stránek uživatele. Tedy potažmo v tom, že SESSION i COOKIES jsou sdílené mezi jednotlivými taby prohlížeče. Když pak uživatel otevře z tabu A (například editace nějakého záznamu) nový tab B a v tomto tabu B se pak dále pohybuje, přepisuje si „historii“ posledních navštívených stránek i pro tab A. Když pak tab B zavře a ve zbylém starém tabu A (editační stránka nějakého záznamu) přejde na naposled navštívenou stránku, vrátí se úplně jinam, než kam by čekal - na stránku, ktero navštívil v (již zavřeném) tabu B dávno po tom, co v tabu A něco editoval.

Dobrá, máme celkem dobře popsaný problém. Jaké je ale řešení? Podařilo se nám přijít na něco docela trikového. Vycházíme z předpokladu, že v Javascriptu můžeme docela pohodlně pracovat s COOKIES a také kontrolovat životní cyklus načtení a opuštění stránky. A právě tyto předpoklady jsou klíčem k tomu, abychom mohli naši SESSION naučit vědět o tom, v jakém tabu prohlížeče právě aplikace běží.

Idea je takováto: každý tab bude nějak „pojmenovaný“, tzn. bude mít své číslo. Tohle číslo tabu bude uloženo v COOKIE a na serveru ho budeme moci využít při přístupu k některým údajům ze SESSION. Tzn. některé vybrané SESSIONs (třeba ta pro zapamatování posledních navštívených stránek) budou „tab-dependent“ – pro každý tab bude použito jiné číslo. Tím docílíme nezávislého uložiště pro každý tab.

Číslo tabu si tedy pamatujeme v COOKIE (cookie s názvem tab). Mimo COOKIE si toto číslo pamatujeme také v property window.name. Pokud tab číslo při načtení stránky nemá, dostane jej. V jiné COOKIE s názvem tabs_counter si také pamatujeme dosud největší přidělené číslo tabu.

Jak ale docílit toho, že nově otevřený tab v rámci stejné SESSION dostane nové číslo? (K takové situaci dojde, když klikneme na odkaz například prostředním tlačítkem myši; nebo při stisknutém Ctrl; nebo vybereme otevření do nového tabu v kontextové nabídce. Situace, kdy je například otevřeno úplně nové okno bez předchozích nastavených COOKIES, řešit nemusíme. Totiž i COOKIE pro sessionId bude úplně nová, SESSION se tedy s žádným jiným oknem/tabem zatím nesdíli a není tedy žádný problém.)

Uděláme to tak, že při načtení stránky do COOKIE identifikující číslo tabu, přiřadíme číslo, dosud maximální číslo tabu + 1. Když pak uživatel klikne na nějaký odkaz například prostředním tlačítkem, nový tab je správně označen tímto novým číslem. To ale není vše. Musíme ještě zajistit, aby se při klasickém kliku na odkaz v původním tabu číslo tabu v COOKIE změnilo zpět na skutečné číslo tabu (dosud tam je nesprávně maximální číslo tabu + 1). K tomu využijeme JS event na objektu window nazvaný onbeforeunload. Ten se zavolá v okamžiku, kdy opouštíme stránku (například když klikneme na odkaz). A na tento event navěsíme „vrácení“ správného čísla tabu i do COOKIE s názvem tab. Kde toto číslo vezmeme? Celou dobu si ho pamatujeme i v property window.name.

Díky tomuto přístupu na frontendu můžeme poté na serveru díky COOKIE s názvem tab identifikovat, ze kterého tabu HTTP request přišel a podle toho se zachovat (využít vlastní historii navštívených stránek atd.). Zatím jsme nezaznamenali žádné nedostatky tohoto řešení a jsme s ním tedy spokojení.

 

Sdílet:
###message