[ Webhosting profitux.cz ]
v6ak [ programování, bezpečnost, web, php, java, ... ] (Vít Šesták)
Buzz - v6ak Twitter - v6ak

štítky

Služby v Javascriptu napříč doménami

Chcete napsat nějakou on-line službu a dát vývojářům API do JavaScriptu, aby ji mohli využívat přímo na svém webu? (Pochopitelně, od klienta.) Pokud znáte XMLHttpRequest či Active-X-ové ekvivalenty pro MS IE, asi víte, že to není to pravé. Narazíte totiž na mezidoménová omezení. Existují však triky, kterými lze tato omezení překonat. Jeden z nich, svůj nápad (i když nevím, jak moc originální, ale jinde se to prý dělá iframem, což se mi nelíbilo), zde ukážu.

U Opery 9.5 jsem zjistil problém, pokud byl poskytovatelský server localhost:82. Když to bylo na v6ak.profitux.cz, jede to i v Opeře. Asi neměla ráda porty, nebo jí vadila url bez tečky v doméně.

Co je zakázáno a co povoleno?

Zakázán je XMLHttpRequest a některá další čtení z jiných domén. Jde o to, že uživatel tam může být přihlášen a jiná stránka, pokud by to měla povolené, by si mohla například číst jeho citlivé informace. Na XMLHttpRequest sice AFAIK existuje nějaká norma umožňující omezit toto omezení jak si cílová stránka přeje, ale co se týče podpory prohlížečů, budeme si muset ještě chvíli počkat.

Vkládat do stránky některé prvky jako skript, obrázek, iframe a další z cizích domén však zakázáno není. Tím můžete danému serveru poslat zprávu. Ale jak vám odpoví?

Příjem odpovědi

Co vím, tak číst zprávu z obrázku přímo stránka nemůže, ten tedy odpadá. Zbývá nám:

iframe

Není to cesta, kterou jsem chtěl popisovat, takže stručně: komunikace zpět probíhá přes část url za křížkem, což je čitelné i mezidoménově.

script

Skript může volat funkce (metody), nastavovat proměnné (vlastnosti) a dělat jinou činnost. Tím dojde k příjmu odpovědi. V podstatě je nutnost používat globální proměnné nebo něco takového. Je však vhodné, když skrtipt zavolá funkci (metodu), protože ta může zavolat příslušný handler.

Identifikace požadavku u ospovědi

Co když chce uživatel API provádět více požadavků zároveň? U XMLHttpRequestu to bylo bez větších problémů možné, tady je to horší. Ale ne nemožné. Stačí každému požadavku přidělit identifikátor unikátní v rámci instance stránky, který bude poslán serveru. Server pak v odpovědi také řekne, k čemu to patří.

Příklad - zdrojový kód

Abych neskončil u teorie, ukážu zdroják. Serverová část je řešena v PHP5. Předpokládám magic_quotes_gpc off. Ukážu poskytnutí služby MD5 hashování. (Asi bych hashoval u klienta nebo na vlastním serveru, to je ale jen příklad.)

Poskytovatel API

Nabízí jednu JS knihovnu a zpracování akce.

soubor Service.js
var Service; (function(){ var loads=[]; Service={ load:function(a, cbck){ var loader = document.createElement('script'); var id = loads.push({ callback:cbck, el:loader }) -1; // uložím callback a element loader.setAttribute('type', 'text/javascript'); loader.setAttribute('src', 'http://poskytovatel/cesta/service.php?a='+encodeURIComponent(a)+'&id='+id); document.body.appendChild(loader); }, // "private" _loaded:function (id, data){ // zavolám loads[id].callback(data); // uklidím var el=loads[id].el; el.parentNode.removeChild(el); delete loads[id]; } }; })();
soubor service.php
<?php // Získám parametry. ////Nechci se obtěžovat s kontrolami zda a co bylo posláno, tak přetypovávám a zavináčuju. Tady to stačí. $id = @( (int)$_GET['id'] ); $a = @( (string)$_GET['a'] ); // pošlu správnou hlavičku, žádný text/html! header('Content-Type: application/x-javascript'); // předám data i s příslušným id echo 'Service._loaded('.$id.', '.json_encode(md5($a)).');';

Uživatel API na straně klienta

soubor index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title></title> <script type="text/javascript" src="http://localhost:82/xs/Service.js"></script> <script type="text/javascript"> function view(x){ alert(x); } </script> </head> <body> <button type="button" onclick="Service.load(prompt('data', ''), view);">načti</button> </body> </html>

Omezení

Diskuzi ke článku naleznete zde.

Linkování

Líbí se Vám tato stránka? Zalinkujte ji!

Chcete sledovat novinky? Pokud si právě prohlížíte článek a hledáte RSS pro celý web, pak jste trošku jinde. Možná hledáte poslední změny.

Validní HTML 4.01 StrictValidní CSS 2.0Validní hlavní RSS kanálPHP 5Apache
referer: UA:CCBot/2.0 (http://commoncrawl.org/faq/) time:0.95469900 1513497106
web
mail
comment