Programování

Sledování vypršení platnosti relace v prohlížeči

Existuje tedy složitá heterogenní webová aplikace s částmi AJAX prováděnými jak ručně, tak pomocí rámců, několika vyskakovacích oken atd. Velký úctyhodný klient vás osloví s požadavkem na zneplatnění, uzavření nebo jinou činnost na celém webu okna aplikace jednou vyprší časový limit relace HTTP. Doufejme, že víte, jak ovládat interval časového limitu relace HTTP, pro webovou aplikaci kompatibilní s J2EE se to děje ze souboru web.xml (na mnoha aplikačních serverech se to však nedělá standardním způsobem). Pro 10minutový časový limit je to:

  10  

Požadavek klienta není vůbec absurdní a z pohledu koncového uživatele má dokonalý smysl, ale pro vývojáře se může stát hroznou bolestí, protože: 1. Nemůžete jen spustit odpočítávání v okně prohlížeče při každém načtení stránky zavřít okno po vypršení časového limitu. Tento přístup fungoval ve světě, který není AJAX, když každá interakce prohlížeč-server vyústila v opětovné načtení okna prohlížeče. 2. Nemůžete dotazovat na serveru, abyste zkontrolovali, zda vypršel časový limit relace HTTP, protože každý takový dotaz bude považován za interakci prohlížeče a serveru prodlužující relaci. To povede k relaci, která nikdy nevyprší. 3. Můžete vytvořit samostatnou webovou aplikaci, která si je vědoma relace HTTP primární webové aplikace a protíná se s ní. Ale to je přehnané a šance na přijetí takového řešení jsou extrémně nízké kvůli možným problémům s integrací. 4. Můžete zkusit zachytit všechny interakce prohlížeče AJAX-server s nějakým pokročilým hackerským kódem a pomůže vám to vypořádat se s vaším aktuálním oknem. To však nefunguje pro případ více otevřených oken - prostě nemůžete komunikovat mezi okny prohlížeče. Jediným způsobem, jak mluvit s nějakým otevřeným oknem z primárního, je použít odkaz na JavaScript v jiném okně a jakmile se primární okno znovu načte nebo přesměruje na jiné místo, ztratí všechny odkazy na JavaScript v ostatních oknech. 5. Nejrealističtějším přístupem je periodické odesílání požadavků XMLHTTP JavaScriptu (z každého otevřeného okna) na server každých {relace max. Neaktivní interval} +10 sekund. To nakonec zavře všechna okna, ale může to mít za následek zavření oken minut (nebo dokonce hodin v závislosti na nastavení časového limitu relace webové aplikace) po zničení relace HTTP, např. jakmile se uživatel odhlásí z primárního okna. Už vám nezbývají žádné možnosti, jste frustrovaní a myslíte si, že je ten pravý čas vzít otcovu zbraň a zítra zastřelit spolužáky ve škole. Ne, ještě ne, dítě - stále existuje cesta ven! Cesta ven není příliš přímočará, ale je velmi elegantní. Cookies nám pomohou. Jeden by si mohl myslet, že doba vypršení platnosti cookies to udělá. Bohužel, jak je popsáno v

tento

článku, nemůžete se spolehnout na dobu vypršení platnosti souboru cookie, protože je měřena prohlížečem klienta, a nikdo nemůže zaručit, že systémové hodiny klienta nezůstanou pozadu o jeden rok. Tady je tedy systém a metoda pro sledování časových limitů relací HTTP v heterogenních webových aplikacích. Na každý požadavek odeslaný z prohlížeče na server jsou pomocí servletového filtru nastaveny dva soubory cookie. Jeden uchovává aktuální čas serveru a druhý uchovává čas vypršení relace. Aktuální čas serveru je potřeba pouze k výpočtu posunu mezi klientem a serverem. Čas vypršení relace se poté pravidelně kontroluje proti _vypočtenému_ aktuálnímu času serveru (pamatujte na offset). Pokaždé, když se na server odešle _any_ požadavek, aktualizuje se cookie doby vypršení platnosti a celá věc prostě funguje. V praxi je tato metoda realizována ve třech krocích: 1. Vytvořte filtr servletu, který by filtroval každý požadavek na vaši webovou aplikaci. Nakonfigurujte jej v souboru web.xml takto:

  SessionTimeoutCookieFilter some.package.SessionTimeoutCookieFilter SessionTimeoutCookieFilter / * 

Nedělejte si starosti s výkonem webové aplikace - tento filtr je VELMI primitivní, vše, co dělá, je přidání dvou souborů cookie k odpovědi:

 public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterChain) hodí IOException, ServletException {HttpServletResponse httpResp = (HttpServletResponse) resp; HttpServletRequest httpReq = (HttpServletRequest) požadavek; longcurTime = System.currentTimeMillis (); dlouhý expiryTime = currencyTime + session.getMaxInactiveInterval () * 1000; Cookie cookie = nový Cookie ("serverTime", "" + currencyTime); cookie.setPath ("/"); httpResp.addCookie (cookie); if (httpReq.getRemoteUser ()! = null) {cookie = nový soubor cookie ("sessionExpiry", "" + expiryTime); } else {cookie = nový Cookie ("sessionExpiry", "" + currencyTime); } cookie.setPath ("/"); httpResponse.addCookie (cookie); filterChain.doFilter (req, resp); } 

Nastavení cesty (v našem případě na „/“) je velmi důležité. Pokud vynecháte nastavení cesty, prohlížeč jej automaticky vypočítá z adresy URL, což bude mít za následek chaos uvnitř úložiště cookies vašeho prohlížeče. 2. Potřebujeme malý JavaScript v každém okně, abychom vypočítali posun mezi časem serveru a klienta. Je třeba ji spustit jen jednou, ale nebylo by na škodu ji spustit při každém načtení stránky:

 funkce calcOffset () {var serverTime = getCookie ('serverTime'); serverTime = serverTime == null? null: Math.abs (serverTime); var clientTimeOffset = (new Date ()). getTime () - serverTime; setCookie ('clientTimeOffset', clientTimeOffset); } window.onLoad = function () {calcOffset (); }; 

3. A nakonec potřebujeme funkci, která by skutečně zkontrolovala, zda relace vypršela. Je třeba jej provádět pravidelně, v našem případě každých 10 sekund (nebo 10 000 milisekund):

 funkce checkSession () {var sessionExpiry = Math.abs (getCookie ('sessionExpiry')); var timeOffset = Math.abs (getCookie ('clientTimeOffset')); var localTime = (nové datum ()). getTime (); if (localTime - timeOffset> (sessionExpiry + 15000)) {// 15 sekund navíc, aby se ujistil window.close (); } else {setTimeout ('checkSession ()', 10 000); }} 

Zavírání oken prohlížeče po vypršení relace je čistá brutalita a může a mělo by být doprovázeno varovnou zprávou, která se objeví jako 1 minuta před vypršením časového limitu relace. Opravdu mě zajímá, abych vás obdržel

kritická zpětná vazba

na moji metodu.

Tento příběh, „Sledování vypršení platnosti relace v prohlížeči“, původně publikoval JavaWorld.