JSONP

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2019. november 5-én felülvizsgált verziótól ; az ellenőrzések 7 szerkesztést igényelnek .

A JSONP vagy a „JSON kitöltéssel” az alap JSON-formátum kiegészítése . Lehetőséget biztosít adatok lekérésére egy másik tartományban található szerverről, amely művelet a tipikus webböngészőkben tiltott a tartománykorlátozási szabályzat miatt .

Történelem

2005 júliusában George Jempty azt javasolta, hogy a JSON elé kerüljön egy opcionális változódeklaráció. [1] [2] Az eredeti JSONP-javaslatot, ahol a kitöltés egy visszahívási funkció, valószínűleg Bob Ippolito készítette 2005 decemberében [3] , és ma már számos Web 2.0 alkalmazás használja, mint például a Dojo Toolkit , a Google Web Toolkit , [4] és Web Services .

A technika leírása

A tartománykorlátozási házirend szerint egy szerveren található weboldalexample1.com nem kapcsolódhat más szerverhez, mint a example2.com. A JSONP technológia azon a tényen alapul, hogy a böngésző biztonsági szabályzata nem tiltja HTML-elemek <script type="text/javascript" src="…"/> használatát az oldal betöltésének kiszolgálójától eltérő szerverekhez. A Open Policy on Elements <script>használatával egyes oldalak arra használják őket, hogy olyan JavaScript-kódot töltsenek be, amely más forrásokból származó, dinamikusan generált JSON-adatokon működik. A JSONP-kérelmek nem JSON-t, hanem tetszőleges JavaScript-kódot kapnak. Ezeket a JavaScript értelmező dolgozza fel, nem a JSON-elemző. A JSONP használata komoly biztonsági kockázatokkal jár, a legtöbb esetben a CORS használata a legjobb választás.

A minta sémája leírható egy adott URL -re küldött kéréssel, amely JSON-adatokat ad vissza. Egy JavaScript program kérheti ezt az URL-t, például az XMLHttpRequest segítségével . Tegyük fel, hogy a Foo objektum UserId-je 1234. Az 1234-es azonosítót átadó URL-t kérő böngészőhttp://server2.example.com/Users/1234 a következő formátumban kap választ:

{ "Név" : "Foo" , "Id" : 1234 , "Ranghely" : 7 }

A harmadik fél válaszában lévő JSON-adatok általában dinamikusan jönnek létre az URL-ben átadott kérési paraméterek alapján.

A következő HTML-elem <script>attribútumként határoz meg egy srchivatkozást, amely JSON-t ad vissza:

< script type = "application/javascript" src = "http://server2.example.com/Users/1234" > </ script >

A böngésző viszont letölti a fájlt , elemzi a tartalmát, blokkkéntscript értelmezi a nyers JSON-adatokat , és szintaktikai hibát dob. Még ha az adatokat JavaScript objektumliterálként értelmezték is, nem érhetők el a böngészőben futó JavaScriptből, mert az objektumliterálok nem érhetők el változóhoz rendelés nélkül.

A JSONP-mintában a címke <script>src attribútuma által mutatott URL függvényhívásba csomagolt JSON-adatokat ad vissza. Ilyen esetben a JavaScript-környezetben már definiált függvény manipulálhatja a JSON-adatokat. A JSONP-kitöltés így nézhet ki:

functionCall ({ "Név" : "Foo" , "Id" : 1234 , "Rank" : 7 });

A függvényhívás a "P" a JSONP szóban - "padding" (töltelék, " indent ") a tiszta JSON körül, vagy egyes források szerint [5] - "előtag". Megállapodás szerint a böngésző a visszahívási függvény nevét elnevezett kérési paraméterként, általában a név jsonpvagy callbacka kérésben szereplő név használatával továbbítja a szervernek, azaz

< script type = "text/javascript" src = "http://server2.example.com/Users/1234?jsonp=parseResponse" > </ script >

Ebben a példában a töltelék a következő lesz:

parseResponse ({ "Név" : "Foo" , "Id" : 1234 , "Ranghely" : 7 });

Töltelék

Míg a kitöltés (előtag) általában egy visszahívási függvény neve, amely a böngészőben a végrehajtási kontextusban van definiálva. A függvény neve mellett az előtag jelenthet változónevet, operátort ifvagy bármely más JavaScript-operátort. A JSONP-kérésre adott válasz (szigorúan véve a JSONP-mintának megfelelő kérés) nem JSON-objektum, és a böngésző nem kezeli ilyenként. A „töltelék” bármilyen JavaScript-kifejezés lehet, és nem szükséges, hogy a JSON benne legyen. De ez általában egy JavaScript-darab, amely függvényhívást alkalmaz bizonyos JSON-adatokra.

Más szavakkal, a JSONP tipikus használata tartományok közötti hozzáférést biztosít egy meglévő JSON API -hoz azáltal, hogy a JSON-kitöltést egy függvényhívásba csomagolja.

Script Elem Injection

A JSONP-nek csak akkor van értelme, ha szkriptelemmel együtt használják. Minden új JSONP-kéréshez a böngészőnek új elemet kell hozzáadnia, <script>vagy egy meglévőt kell használnia. Az első manipuláció, egy új szkriptelem hozzáadása, dinamikus DOM-manipulációval történik, és az úgynevezett szkriptelem-injektálás . Az elem <script>beszúrásra kerül a HTML DOM-ba, a kívánt JSONP-végpont URL-címével az „src” attribútumban.

Ezt a dinamikus szkriptelem-injektálást általában egy javascript segédkönyvtár végzi. A jQuery és más keretrendszerek segédfunkciókkal rendelkeznek a JSONP számára; külön megoldások is vannak [6] [7] .

A JSONP-hívásokhoz dinamikusan beillesztett szkriptelem így néz ki:

< script type = "text/javascript" src = "http://server2.example.com/Users/1234?jsonp=parseResponse" > </ script >

Az elem beillesztése után a böngésző feldolgozza azt, és HTTP GET-et hajt végre az src URL-címen, lekérve a tartalmat. A böngésző ezután JavaScriptként kezeli a visszaadott terhelést. Általában ez egy függvény végrehajtása.

Ebben az értelemben a JSONP használata úgy írható le, mint amely lehetővé teszi a böngészőoldalak számára, hogy megkerüljék a tartománykorlátozási házirendet egy szkriptelem beszúrásával.

Biztonsági szempontok

A más szerverekről származó szkriptcímkék bevonása lehetővé teszi a távoli szerverek számára, hogy bármilyen tartalmat keverjenek a webhelyen . Ha a távoli kiszolgálókon olyan biztonsági rések vannak, amelyek lehetővé teszik a JavaScript keverését, az eredeti szerver által biztosított oldal fokozott kockázatnak van kitéve.

Jelenleg folynak a lépések a JSON-P [8] biztonságosabb, szigorúbb részhalmazának meghatározására, amelyet a böngészők kényszeríthetnek arra, hogy egy adott MIME-típusú szkriptet kérjenek, például "application/json-p". Ha a válasz nincs szigorú JSON-P-ként értelmezve, a böngésző hibát jelezhet, vagy egyszerűen figyelmen kívül hagyja a teljes választ. Jelenleg azonban a JSONP egyetlen érvényes MIME-típusa az „application/javascript” [9] .

Webhelyek közötti kérés hamisítása

A primitív JSONP gazdagépek érzékenyek a helyek közötti kérés-hamisításra (CSRF vagy XSRF) [10] . Mivel a HTML-címkére <script>nem vonatkozik a tartománykorlátozási szabályzat a valós böngészőmegvalósításokban, egy rosszindulatú oldal kérhet és fogadhat egy másik webhelyhez tartozó JSON-adatokat. Ez lehetővé teszi, hogy a JSON-adatokat rosszindulatú oldallal összefüggésben feldolgozzák, és esetleg jelszavakat vagy más érzékeny adatokat fedjenek fel, ha a felhasználó egy másik webhelyre van bejelentkezve.

Ez csak akkor okoz problémákat, ha a JSON-kódolású adatok érzékeny információkat tartalmaznak, amelyeket nem szabad harmadik félnek felfedni, és a szerver a böngésző tartománykorlátozási házirendjére támaszkodik, hogy blokkolja az adatátvitelt rossz kérés esetén. A probléma nem áll fenn, ha a szerver maga határozza meg a kérés megfelelőségét, és csak akkor ad át adatokat, ha a kérés érvényes. A sütik önmagukban nem alkalmasak a kérés jogosságának meghatározására. A cookie-k használata önmagában is ki van téve a webhelyek közötti kérés-hamisításnak .

JSONPP

JSONPP ( eng.  paraméteres JSON padding  - "parameterized JSON with padding") - a JSONP ötlet fejlesztése.

A JSONPP tartalmazza a forrás URL-t, a JSON-adatokat feldolgozó függvény nevét, az adatok beérkezése utáni eval karakterláncot és az adatok befejezésekor értékelendő karakterláncot:

JSON_call ( SRC , JSONP , JSONPP , ONLOAD );

végül megfordul

ans = JSONP ( SRC ) { eval ( JSONPP ( ans )); eval ( ONLOAD ); }

Általában a paraméterek száma nem fontos magának a JSONPP-ötletnek. SRC, JSONP, JSONPP (és ezek feldolgozása a szerver oldalon, majd a kliens oldalon) elég ahhoz, hogy JSONPP legyen. Tekintsük az S3DB szolgáltatással való munka példáját.

function s3db_jsonpp_call ( src , next_eval ){ var call = "call_" + Math . véletlenszerű (). toString (). csere ( /\./g , "" ); var headID = dokumentum . getElementsByTagName ( "fej" )[ 0 ]; var script = dokumentum . createElement ( 'script' ); forgatókönyv . id = hívás ; forgatókönyv . type = 'text/javascript' ; // párnázott, paraméterezett json használatával src = src + "&format=json&jsonp=s3db_jsonpp&jsonpp=" + next_eval + "&onload=remove_element_by_id('" + script . id + "')" ; forgatókönyv . src = src ; fejazonosító . appendChild ( script ); // válasz lekérése } function s3db_jsonpp ( ans , jsonpp ){ eval ( jsonpp ); return ans ; } function remove_element_by_id ( id ){ var e = document . getElementById ( id ); e . szülőcsomópont . RemoveChild ( e ); return false ; }

A példában a függvény s3db_jsonpp_call()létrehoz egy szkriptelemet a DOM fejrészében, amelynek src-je megegyezik a JSONPP-hívással.

Miután megkapta a választ a kiszolgálótól, meg lesz hívva s3db_jsonpp() - a hívási paraméterekben átadásra kerül, ahogyan a JSONP szabályok szerint kell.

Belsőleg s3db_jsonpp()működni fog eval(jsonpp), és az ans értékét visszaadjuk.

A hívás a létrehozott szkript azonosítójával a fejben eval(onload)a végrehajtáshoz vezet, remove_element_by_id()és ennek eredményeként annak törléséhez, mert úgysem kerül felhasználásra, mivel a példában szereplő id véletlenszerűen generált a függvény legelején s3db_jsonpp_call(). Ez a hívás a szerver válaszában van.

Jegyzetek

  1. JSON (lefelé irányuló kapcsolat) értékelése (2005. július 19.). Az eredetiből archiválva: 2006. február 12. 
  2. json: Üzenet: Re: Megjegyzések (downlink) (2005. augusztus 17.). Az eredetiből archiválva : 2013. január 17. 
  3. Távoli JSON – JSONP (lefelé irányuló kapcsolat) . from __future__ import * . Bob.pythonmac.org (2005. december 5.). Letöltve: 2008. szeptember 8. Az eredetiből archiválva : 2013. január 17.. 
  4. GWT oktatóanyag: Web Services ügyféloldali olvasása JSONP segítségével (lefelé mutató kapcsolat) . Google Web Toolkit alkalmazások (2008. február 6.). Letöltve: 2009. július 3. Az eredetiből archiválva : 2013. január 17.. 
  5. A kísérleti RDF eredmény beállítása JSON-fordítóra (lefelé irányuló kapcsolat) . Hozzáférés dátuma: 2012. február 20. Az eredetiből archiválva : 2013. január 17. 
  6. példa jsonp könyvtár a pastebin-en (downlink) . Az eredetiből archiválva : 2013. január 17. 
  7. A jQuery $.getJSON segédprogramja (lefelé irányuló kapcsolat) . Az eredetiből archiválva : 2013. január 17. 
  8. Biztonságosabb tartományok közötti Ajax JSON-P/JSONP-vel (lefelé irányuló kapcsolat) . JSON-P.org . Letöltve: 2011. október 30. Az eredetiből archiválva : 2013. január 17.. 
  9. Gray, Eli Biztonságos ez a JSONP biztosításához? (nem elérhető link) . stackoverflow.com (2010. június 27.). Letöltve: 2012. szeptember 7. Az eredetiből archiválva : 2013. február 13.. 
  10. Grossman, Jeremiah Advanced Web Attack Techniques with Gmail (downlink) (2006. január 27.). Letöltve: 2009. július 3. Az eredetiből archiválva : 2013. január 17.. 

Linkek