Leggyakrabban talán JSON stringek objektumokká alakításakor jön elő ez a probléma. Az Adobe AIR környezet biztonsági okokból korlátozza az eval() javascript metódust. Ez a szigor erősen indokolt, de nem okoz megoldhatatlan problémát.
Nézzük a megoldást, de előbb az okokat, amiért így lett kialakítva a futtatókörnyezet.
Valamit valamiért, avagy amiért nincs eval().
MIt csinál az eval()? Végrehajt egy string formában megadott javascript kódsort, minden előztetes cécó nélkül.
Az AIRből pedig kivették azt a biztonsági szigorítást, hogy AJAX kérések csak azon a domainen futhatnak, ahol az oldal amit látogatunk. Bárhonnan fogadhatunk akármilyen javascript kódokat, akár fileszinten is betáplálva az alkalmazásunkba.
Ez eléggé hasznos, révén így igazi, online forrásokra támaszkodó, nyitott API-kat nyújtó webszolgáltatásokat kihasználó alkalmazást alkothatunk. De veszélyeket is rejt, révén az AIR alkalmazásunk hozzáfér a kliens filerendszeréhez. Nem lenne túl jó, ha egy pl egy chatprogram evalozott JSON stringjeiben tudatlanul kiadnánk személyesebb adatokat tartalmazó fájljainkat.
Az alkalmazásunk egy izolált környezetben fut, angol nevén ez a sandbox. Ezen belül vezették be az Adobe fejlesztői az alábbi szigorításokat:
Karantén, avagy a non-application sandbox
Lehetőségünk van több ilyen sandbox-ot létrehozni, hogy ne akadjanak össze esetleg a használt rendszerek. Ezekben a “karanténokban” ismét visszakapjuk az eval()-t, újra megvan a domainre vonatkozó szigor, de semmit se láthatunk magából az AIR futtatókörnyezetből.
Ezeket például IFRAME -ek segítségével valósíthatjuk meg, az alkalmazás html kódjába helyezve valami hasonlót:
<iframe id="frameId" sandboxRoot="http://plurk.com/" documentRoot="app:/" src="nonapp_sandbox.html" frameborder="0" height="0" width="0"></iframe>
ID - amivel majd DOMon keresztül hivatkozunk rá
sandboxRoot - az a domain amire a karanténon belül szűkítjük a lekéréseket
documentRoot - amennyiben ez “app:/”, akkor kapunk megfelelő non-application sandbox -ot
src - a html amit betöltünk majd az IFRAME-be

Most, hogy van egy szeparált környezetünk, ahol működik az eval(), már csak össze kell kötni a két sandbox-ot. Ezt az AIR egy childSandboxBridge nevű interfészen keresztül tudja megvalósítani.
Az IFRAME-be dugott htmlben hozzunk létre pár függvényt. Először definiálni kell mit akarunk az IFRAME-en kívülre adni a childSandboxBridge-en keresztül.
1 2 3 4 | /* nonapp_sandbox.html */ window.onLoad = function(){ window.childSandboxBridge = {'myEval': myEval}; } |
Majd definiáljuk magát a függvényt amit átadunk.
4 5 6 7 | /* nonapp_sandbox.html */ function myEval(str){ return eval(str); } |
Tehát maga az eval() ebben a zárt környezetben fut le, a végeredményt adja át az alkalmazásnak. Bármi ártalmas kód ami itt végrehajtódik, próbálhozhat, nem fér hozzá az AIR környezethez, s azon keresztül a rendszerhez.
Az alkalmazásunkban onLoad eseménykor definiáljuk a childSandboxBridge interfészen át kapott függvényt.
1 2 3 4 | /* application.html */ window.onLoad = function(){ window.myEval = document.getElementById('frameId').contentWindow.childSandboxBridge.myEval; } |
És ennyi, most már használhatjuk eval helyett ezt a saját függvényt. Még kényelmesebb, ha pl az általunk használt javascript keretrendszer érzékenyebb részeit módosítjuk úgy, hogy működjenek ezen az interfészen keresztül, és akkor későbbiekben már észre se vesszük ezt a problémát.
10 11 | /* application.html */ var evaledCode = window.myEval( code_string ); |
Eddig az Adobe AIR-ről:
Az AIR security modelljének az a tulajdonsága, hogy a body onload() esemény után kikapcsolja a stringek JS parse-olását, más esetekben is problémás lehet. Például ha a DOM-hoz új node-okat akarsz hozzáadni, nem tudsz könnyen az onclick eseményeikhez eseménykezelőket rendelni, mivel nem kerül kiértékelésre a string formájában megadott JS függvényhívás. Ebben az esetben hasznos, ha ismeri az ember a JavaScript scope és closure-okat. Ez a cikk nagyon jól elmagyarázza hogy ezek hogyan működnek:
http://tinyurl.com/4fjlwa