Javascript oldali tömörítés postoláskor
Avagy hogyan csökkentsük a forgalmunkat a kliens-szerver között.
Nem mondható mindennapos problémának, amivel találkoztam, éppen ezért kis bosszúságot is okozott, hogy miért nem sikerül egy egyszerű POST küldés a kliensoldalról a szerver felé. Rövid leírás, a túlméretes POST forgalomkezelésről.
Picit részletesebben a problémáról.
Amikor egy nagyobb adathalmazt kell feldolgoznunk kliens oldalon és azt vissza kell küldenünk a szervernek további munkára, feldolgozásra, akkor többszörösen is gátakba ütközhetünk. Nevezetesen a PHP - post_max_size , a másik a Suhosin modul – „suhosin.post.max_” kezdetű változói, azokon belül is a suhosin.post.max_value_length. Most nem merülünk bele a PHP konfigurálásába, abból indulunk ki, hogy azokat a szolgáltató nem engedi állítgatni, biztonsági okokból.
A fenti két paraméter a POST küldéskor, maga a POST tömb méretét, illetve egy-egy POST változó méretét korlátozza. Ez az én esetemben igen kellemetlen volt, lévén, hogy egy közel 1,5MB szövegmérettel rendelkező JSON stringet akartam a szervernek küldeni. Ugye az első lépés, hogy engedünk a kísértésnek és megemeljük (enyhítünk) a biztonsági beállításokon. De ezt a rendszergazda nem nézi jó szemmel, illetve nem teszi lehetővé, hogy magunk állítgassuk e paramétereket.
A megoldás sokkal egyszerűbb, mint gondolnánk, a POST küldés előtt a szerializált adatot, vagy esetünkben magát a JSON stringet be kell tömöríteni, amit majd szerveroldalon értelemszerűen kicsomagolunk. Részemről a DEFLATE-re esett a választás, javascript alá egy megfelelően gyors portolást is találni (https://github.com/dankogai/js-deflate) és a PHP és natívan kezeli.
Megvalósítás Javascriptben, kliens oldalon
var data = Base64.encode(RawDeflate.deflate('jsonString')); // ne feledjük el betölteni a Dankogai rawdeflate.js-t
A tömörített adatot még futtassuk át egy Base64 kódoláson, így megszabadulunk az extra/különleges karakterektől, amik miatt esetleg fennakadna az adatátvitel.
A Base64 kódolást és dekódolást sajnos az IE8-9 még nem támogatja natívan (btoa - atob), így ha böngésző kompatibilisek akarunk maradni, akkor a (http://www.webtoolkit.info/javascript-base64.html) scriptjét tudjuk használni.
Megvalósítás PHP-ban, szerver oldalon
$value = gzinflate(base64_decode(preg_replace('/\s/', '+',$_POST['data'])));
A kicsomagolás előtt, ugye szükség van a Base64 dekódolásra, illetve még a Base64 dekódolás előtt a kapott POST ['data'] tartalmában kicserélünk minden szóközt, '+' jelre.
A PHP 5.1.0 verzió óta ugyanis a base64_decode nem feltételezi, hogy a kapott adatban a szóköz automatikusan + jel lenne, ezt nekünk kell előtte fixálni.
Így jelentősen csökkentjük a POST tömbünk méretét, ezért a fent említett biztonsági paraméterek mellett is jó darabig működni fog a POST küldés. Nem mellesleg csökkentjük a hálózati forgalmat is.