facebook twitter iwiw google buzz

Ajax válaszok cache-elése - böngésző teszt

2010. október 30. | Szerző: Árva-Tóth Mihály | címkék: , ,

Ajax logoGondoltad volna, hogy 2010 harmadik negyedévében csak egyetlen olyan böngésző van, amely minden tekintetben helyesen kezeli az Ajax válaszok HTTP fejlécben definiált gyorstárazás információkat? Pedig ez a szomorú helyzet. Lehull a lepel: kezdődjön a nagy böngészőteszt!

Az interneten keresgélve olyan oldalakra lehet bukkanni, ahol a fejlesztők az Ajax válaszok gyorstárazásának megakadályozásán fáradoznak, olyan erőforrásokat viszont, ahol pont ellenkezője lenne a fontos, gyakorlatilag nem találni.

Példa HTML forráskódFejlesztéseink során viszonylag hamar eljutottunk odáig, hogy kihasználnánk a különböző Cache-Control, Expires, Last-Modified stb. HTTP fejlécek adta lehetőségeket Ajax válaszok cache-elésére. Már elöljáróban elmondom, hogy nem feltételeztük azt, hogy minden böngésző alatt ugyanúgy működik majd minden, de erre még mi sem számítottunk.

Tesztkörnyezet

Létrehoztunk egy statikus HTML állományt, ami gyakorlatilag üres div-eket tartalmazott id attribútumokkal, plusz néhány gomb került még ki, amiket felprogramoztunk onClick-re. Ilyenkor lefuttattunk egy Ajax kérést, ami lekért egy olyan erőforrást, ami néhány karakteres szövegen kívül megfelelő HTTP fejlécekkel tért vissza. Lássuk a három variációt:

1. Semmilyen cache-eléssel összefüggő fejlécet nem küldtünk ki

Ez a legegyszerűbb eset, az alábbi fejlécek tartoztak a válaszhoz:

Date: Fri, 16 Jul 2010 12:36:56 GMT
Content-Encoding: gzip
Content-Length: 73
Keep-Alive: timeout=3, max=100
Connection: Keep-Alive
Content-Type: text/html

2. Gyorstárazás megengedett, jövőbeni időpontot definiáltunk

Ebben az esetben elláttuk a választ Cache-Control, Expires, Last-Modified headerekkel:

Date: Fri, 16 Jul 2010 12:36:53 GMT
Expires: Fri, 16 Jul 2010 12:38:53 GMT
Cache-Control: public, max-age=120
Last-Modified: Fri, 16 Jul 2010 12:36:53 GMT
Content-Encoding: gzip
Content-Length: 73
Keep-Alive: timeout=3, max=100
Connection: Keep-Alive
Content-Type: text/html

3. Semmilyen böngésző cache nem engedélyezett

Végül bevetettük a szokásos fejléceket, amikkel le lehet tiltani az erőforrás böngésző általi cache-elését:

Date: Fri, 16 Jul 2010 12:41:08 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Expires: Fri, 16 Jul 2010 00:00:00 GMT
Last-Modified: Fri, 16 Jul 2010 12:41:08 GMT
Content-Encoding: gzip
Content-Length: 73
Keep-Alive: timeout=3, max=100
Connection: Keep-Alive
Content-Type: text/html

Elvárt működés

Vegyük sorra az eseteket:

  1. 304-es HTTP válaszkódHa nem küldünk ki semmilyen plusz headert, akkor minden egyes alkalommal, amikor gombra kattintok, a böngészőknek kutya kötelességük lenne elküldeni az Ajax kérést conditional GET formában (azaz If-Modified-Since vagy If-None-Match fejlécekkel), lévén más utasítást nem kaptak — sem azt, hogy gyorstárazhatják az erőforrást sem azt, hogy nem. Erre a kérésre megengedett a szerver 304 Not Modified válasza.
  2. Ha megengedjük a cache-elést, akkor az első lekérdezés utáni klikkelésre már nem szabad, hogy elmenjen kérés a szerver felé, a tartalmat ilyenkor a belső cache-ből kell vennie a böngészőnek. Azonban amint lejár az erőforráshoz tartozó cache-time, az azt követő klikkelésre ismét el kell, hogy menjen a kérés. Erre a kérésre is megengedett a szerver 304 Not Modified válasza.
  3. Ha pedig explicit tiltjuk a gyorstárazást, akkor hasonlóan az első esethez, a kliensnek minden egyes klikkelésre el kell küldenie kérését. A kliens nem conditional GET requestet küld, ezért a szerver nem válaszolhat 304-es HTTP kóddal.

Tapasztalt működés

  Normál válasz Cache-elhető válasz Nem cache-elhető válasz
Internet Explorer 8.0 HIBÁS OK OK
Mozilla Firefox 3.6 HIBÁS OK OK
Opera 10.60 RÉSZLEGES HIBÁS OK
Chrome 5.0 OK OK OK
Safari 5.0 RÉSZLEGES HIBÁS OK

 

Az Internet Explorer 8.0 számunkra meglepő módon nem ott hasalt el ahol vártuk. Remekül vette az akadályt: a Cache-Controlban meghatározott idő után ismét elküldte a kérést, azelőtt viszont nem. Ellenben ha az Ajax válasz semmilyen gyorstárazással kapcsolatos fejlécet nem tartalmaz, akkor már hiába kattintottunk a gombra, nem ment el kérés. Új kérést már csak akkor tudtunk kicsikarni, ha a keretként szolgáló statikus HTML-t újratöltöttük.

A Firefox 3.6 sincs jobb helyzetben, viselkedése megegyezik az IE-vel.

Az Opera 10.60 kullog a sor legvégén. Egyáltalán nem kezeli le a jövőbeni gyorstározást, akármennyit állítunk be a Cache-Control fejlécben, mindig minden klikkelésre elmegy a kérés. A normál válasz oszlopban azért kapott „részlegesen” cimkét mert bár igaz, hogy itt az elvárt működés az, hogy elmenjen a kérés minden klikkelésre, viszont ennek conditional GET formájában kellene történnie (megfelelő request headerek). Viszont az Opera nem küld feltételes fejléceket, így a webszervernek kötelessége 200-as HTTP kóddal válaszolnia.

A bevezetőben említett egyetlen böngésző nem más, mint a Google Chrome, ami minden akadályt pont úgy vett, ahogy az elvárt működésben szerepel. Normál válasz esetén mindig elküldi a kérését, feltételes fejlécekkel együtt; a gyorstárazás lejárta után pedig szépen lekérdezi újra az erőforrást.

Végére maradt a Safari 5.0 (mármint nálunk a felsorolásban), ami működését tekintve pontosan megegyezik az Operával.

Konklúzió

Egyik szemünk sírt... A tesztek elvégzése után nem tudtuk hirtelen, hogy sírjunk vagy nevessünk, inkább az előbbit választottuk. Józan paraszti ésszel ugyanis elég nehéz felfogni, hogy ha egy böngésző normál lekérdezés esetén mindenben jól működik, akkor XML HTTP request esetén miért okoz gondot? Végül letettünk arról a tervünkről, hogy fejlesztéseink során ezt a metódust válasszuk az Ajax kérések kliens oldali gyorstárazására. Találtunk jobb megoldást a localStorage „személyében”, de erről majd egy legközelebbi cikkben.

További friss bejegyzések