Programmering

Sporingsøktens utløp i nettleseren

Så det er den komplekse heterogene webapplikasjonen, med AJAX-deler gjort både manuelt og med rammer, flere popup-vinduer osv. En stor respektabel klient nærmer deg deg med et krav om å ugyldiggjøre, lukke eller utføre annen aktivitet på hele nettet applikasjonsvinduer når HTTP-økt går ut. Forhåpentligvis vet du hvordan du kontrollerer tidsavbruddsintervallet for HTTP-økt, for et J2EE-kompatibelt webapplikasjon gjøres det fra en web.xml-fil (men i mange app-servere gjøres det ikke på en standard måte). I en 10-minutters tidsavbrudd er det:

  10  

Klientkravet er ikke absurd i det hele tatt, og gir perfekt mening fra sluttbrukerperspektivet, men det kan bli en forferdelig smerte for en utvikler fordi: 1. Du kan ikke bare starte en nedtellingstidsur i nettleservinduet hver gang siden lastes inn for å lukke vinduet ved timeout. Denne tilnærmingen fungerte i en ikke-AJAX-verden når hver nettleser-server-interaksjon resulterte i at nettleservinduet ble lastet inn på nytt. 2. Du kan ikke spørre serveren for å sjekke om HTTP-økt har tidsavbrudd eller ikke, da hvert slikt spørsmål blir behandlet som en nettleser-server-interaksjon som forlenger økten. Dette vil føre til en økt som aldri utløper. 3. Du kan opprette en egen webapplikasjon som er klar over den primære webappens HTTP-økt og krysser den. Men det er for mye, og sjansene for at en slik løsning blir akseptert er ekstremt lave på grunn av integrasjonsproblemer som sannsynligvis vil oppstå. 4. Du kan prøve å fange opp alle AJAX nettleser-server-interaksjoner med noen avanserte hack-lignende koder, og det vil hjelpe deg å håndtere ditt nåværende vindu. Men dette fungerer ikke for saken med flere åpne vinduer - du kan bare ikke kommunisere mellom nettleservinduer. Den eneste måten å snakke med et åpent vindu fra et primært vindu, er å bruke JavaScript-referansen til et annet vindu, og når primærvinduet lastes om eller rettes til et annet sted, mister det alle JavaScript-referanser til andre vinduer. 5. Den mest realistiske tilnærmingen er å sende periodiske JavaScript-XMLHTTP-forespørsler (fra hvert åpne vindu) til serveren hver {økt maks inaktivt intervall} +10 sekunder. Dette vil til slutt lukke alle vinduer, men kan føre til at vinduene lukkes minutter (eller til og med timer, avhengig av tidsavbruddsinnstillingen for nettappen) etter at HTTP-økten blir ødelagt, f.eks. når brukeren logger ut fra hovedvinduet. Ingen flere valgmuligheter igjen, du er frustrert og du tror at det er akkurat det rette tidspunktet å ta pappas pistol og skyte klassekameratene dine på skolen i morgen. Nei, ennå ikke barn - det er fremdeles en vei ut! Veien ut er ikke veldig grei, men er veldig elegant. Cookies vil hjelpe oss. Man kan tro at utløpstid for informasjonskapsler ville gjøre susen. Dessverre, som beskrevet i

dette

artikkel, kan du ikke stole på informasjonskapselens utløpstid siden den måles av en klientleser, og ingen kan garantere at klientsystemets klokke ikke er ett år etter. Så, her er systemet og metoden for sporing av HTTP-sesjons tidsavbrudd i heterogene webapplikasjoner. På hver forespørsel fra en nettleser til en server blir to informasjonskapsler satt av et servletfilter. En holder serverens nåværende tid, og en annen holder utløpetiden for økten. Serverens aktuelle tid er bare nødvendig for å beregne en forskyvning mellom klient og server. Øktens utløpstid blir deretter sjekket med jevne mellom den _beregnede_ gjeldende servertiden (husk forskyvningen). Hver gang _any_ forespørsel blir gjort til serveren oppdateres informasjonskapselen for utløpstid, og det hele fungerer bare. I praksis blir denne metoden realisert i bare tre trinn: 1. Lag et servletfilter som vil filtrere hver forespørsel til webapplikasjonen. Konfigurer den i web.xml slik:

  SessionTimeoutCookieFilter some.package.SessionTimeoutCookieFilter SessionTimeoutCookieFilter / * 

Ikke bekymre deg for ytelsen til nettappene dine - dette filteret er veldig primitivt, alt det gjør er å legge til to informasjonskapsler i svaret:

 public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterChain) kaster IOException, ServletException {HttpServletResponse httpResp = (HttpServletResponse) resp; HttpServletRequest httpReq = (HttpServletRequest) req; lang currTime = System.currentTimeMillis (); long expiryTime = currTime + session.getMaxInactiveInterval () * 1000; Cookie cookie = ny Cookie ("serverTime", "" + currTime); cookie.setPath ("/"); httpResp.addCookie (informasjonskapsel); hvis (httpReq.getRemoteUser ()! = null) {cookie = ny informasjonskapsel ("sessionExpiry", "" + expiryTime); } annet {cookie = ny informasjonskapsel ("sessionExpiry", "" + currTime); } cookie.setPath ("/"); httpResponse.addCookie (informasjonskapsel); filterChain.doFilter (req, resp); } 

Å sette sti (til "/" i vårt tilfelle) er veldig viktig. Hvis du utelater stiinnstilling, vil nettleseren automatisk beregne den fra URL-en, noe som vil føre til kaos i lagring av informasjonskapsler. 2. Vi trenger et lite JavaScript i hvert vindu for å beregne forskyvning mellom server og klienttid. Det må kjøres bare en gang, men det ville ikke skade å kjøre det på hver sideinnlasting:

 funksjon calcOffset () {var serverTime = getCookie ('serverTime'); serverTime = serverTime == null? null: Math.abs (serverTime); var clientTimeOffset = (ny dato ()). getTime () - servertid; setCookie ('clientTimeOffset', clientTimeOffset); } window.onLoad = funksjon () {calcOffset (); }; 

3. Og til slutt trenger vi en funksjon som faktisk vil sjekke om økten er tidsavbrutt. Det må utføres med jevne mellomrom, i vårt tilfelle hvert 10. sekund (eller 10000 millisekunder):

 function checkSession () {var sessionExpiry = Math.abs (getCookie ('sessionExpiry')); var timeOffset = Math.abs (getCookie ('clientTimeOffset')); var localTime = (ny dato ()). getTime (); hvis (localTime - timeOffset> (sessionExpiry + 15000)) {// 15 ekstra sekunder for å sikre at window.close (); } annet {setTimeout ('checkSession ()', 10000); }} 

Faktisk er det å lukke nettleservinduer etter utløpet av ren brutalitet, og det kan og bør ledsages av en advarsel som dukker opp som 1 minutt før økten går ut. Jeg er veldig interessert i å motta din

kritisk tilbakemelding

på metoden min.

Denne historien, "Tracking session expiration in browser" ble opprinnelig publisert av JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found