Gondoltad 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.
Fejleszté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:
Ha 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.- 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.
- 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ó
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.
