Tunneling e proxy server per Ajax e non solo
lunedì 10 dicembre, 2007A causa della sua capacità di comunicare con il server, l'oggetto XmlHttpRequest (XHR), usato nella tecnologia Ajax (acronimo di Asynchronous JavaScript and XML, la cui pronuncia dovrebbe essere "egiacs" anche se noi italiani preferiamo "aiacs"), ha un blocco di protezione che gli impedisce di eseguire richieste esterne al dominio in cui opera. Questa protezione è necessaria per impedire Injection Javascript (tecniche di "iniezione" di codice estremamente pericoloso con lo scopo di violare il sistema) di svariato tipo, con l'obiettivo ultimo di "irrompere" nel sistema.
Questo limite è oggi tenuto in seria considerazione e si sta pensando, in qualche modo, di risolverlo - direttamente nell'oggetto XmlHttpRequest - senza pregiudicare la sicurezza (vedi anche: Third proposal for cross-site extensions to XMLHttpRequest ).
Comunque sia la situazione oggi è la seguente:
Il codice Javascript che usa l'oggetto XmlHttpRequest (presente nella pagina yourWebApp.html) può fare richieste esclusivamente verso il dominio miodominio.com, cioè al dominio a cui appartiene il codice Javascript. Uno scenario diquesto tipo, quindi:
...non funzionerà!
Inoltre, come indicato su The Same Origin Policy di Mozilla:
[..] Mozilla considers two pages to have the same origin if the protocol, port (if given), and host are the same for both pages. To illustrate, this table gives examples of origin comparisons to the URL http://store.company.com/dir/page.html.
![]()
Non è solo il dominio a rendere le cose difficili. In aggiunta considerate che ogni browser ha una sua implementazione dell'oggetto XmlHttpRequest e quindi sue regole personali.
Comunque sia per risolvere il problema esistono varie tecniche.
1. Proxy Server
Questa tecnica sfrutta un linguaggio lato server per "ingannare", per così dire, l'oggetto XHR in modo tale da creare un tunnel tra l'oggetto XHR e il nostro dominio esterno target. Il PHP, ad esempio, è in grado di recuperare informazioni da altri domini in vari modi, in base anche al tipo di installazione e restrizioni impostate sul nostro server. Nel caso generale quello che si tende a fare è questo:
In poche parole l'oggetto XHR colloquia con il nostro dominio, dove una pagina appositamente scritta recupera le informazioni da un dominio esterno. Si realizza quindi un proxy in PHP, cioè una "pagina tramite" che recupera le informazioni per noi, restituendole all'oggetto XHR. Uno dei più semplici proxy server è proprosto, ad esempio, da Yahoo:
-
<?php
-
// PHP Proxy example for Yahoo! Web services.
-
// Responds to both HTTP GET and POST requests
-
//
-
// Author: Jason Levitt
-
// December 7th, 2005
-
//
-
-
// Allowed hostname (api.local and api.travel are also possible here)
-
-
// Get the REST call path from the AJAX application
-
// Is it a POST or a GET?
-
$path = ($_POST['yws_path']) ? $_POST['yws_path'] : $_GET['yws_path'];
-
$url = HOSTNAME.$path;
-
-
// Open the Curl session
-
-
// If it's a POST, put the POST data in the body
-
if ($_POST['yws_path']) {
-
$postvars = '';
-
}
-
}
-
-
// Don't return HTTP headers. Do return the contents of the call
-
-
// Make the call
-
-
// The web service returns XML. Set the Content-Type appropriately
-
-
echo $xml;
-
?>
In questo codcie si fa uso delle curl, una nota libreria PHP usata per bypassare eventuali restrizioni sui più semplici e noti comandi di fopen(), fread() etc... Basterebbe, infatti, aprire la destinazione sul nostro dominio esterno con una delle tante funzioni messe a disposzione da PHP, come readfile(). Sfortunatamente, spesso, queste funzioni sono disabilitate o limitate su alcuni hosting, per questioni di sicurezza. Le curl, tuttavia, sono quasi sempre disponibili.
2. Il buon vecchio TAG IFRAME
Ricordo ancora quando nel 1996 implementai una delle prime tecniche di Remote Scripting (come veniva chiamato all'epoca, quando Ajax era solo un detersivo). Il TAG IFRAME è oggi ancora usato, abusato, adorato e disprezzato, in dipendenza del programmatore che lo usa. Il TAG IFRAME viene spesso additato come "cosa da non fare", una pericolosa porta per un hacker. Ultimamente, poi, con l'introduzione nei browser dell'oggetto XmlHttpRequest, l'IFRAME è stato disprezzato ancor di più dai "puristi Ajax". In realtà è usato ancora molto, sia per l'inserimento di Widgets, Gadgets e Antipixel nei Blog (se avete un Blog è probabile che la vostra pagina sia piena di "buchi" IFRAME e nemmeno lo sapete), sia per bypassare l'eventuale blocco o mancanza dello stesso oggetto XmlHttpRequest.
Un IFRAME apre di fatto un browser all'interno del browser. Questa finestra IFRAME può visualizzare un dominio esterno ed è accessibile dal codice Javascript presente nella pagina madre. Ecco quindi un modo diverso per bypassare il blocco dell'oggetto XmlHttpRequest.
3. Altre tecniche
Esistono poi numerose altre alternative a seconda dei casi e delle circostanze in cui ci troviamo (possibilità di installare tool specifici o manipolare il Web Server a basso livello). Si può usare il mod_rewrite o mod_proxy di apache o librerie come JSON per superare il problema.
Altre tecniche (segui i link più sotto sul "vedi anche") sono simpatiche varianti, tuttavia alcune hanno restrizioni sui browser che le supportano, quindi attenti. La migliore, almeno a mio parere, rimane l'uso di un semplice proxy server in PHP.
4. Flash
Mi permetto di inserire Flash tra le tecniche di superamento del cross-domain, non foss'altro in quanto l'ho citato in un precedente Post: Ajax senza HTTPRequest. Flash, ovviamente, non ha niente a che fare con l'oggetto XHR e, più che mai, niente a che fare con Javascript. Tuttavia bisogna tenere a mente alcuni importanti caratteristiche:
- Un filmato Flash può interagire con Javascript e il DOM della pagina Web
- Javascript può interagire con un filmato Flash
- Adobe AIR è un sistema in cui HTML, Javascript/Ajax e Flash convivono in modo armonico e funzionale
Flash, a differenza dell'oggetto XHR, non ha restrizioni così vincolanti sull'accesso cross-domain. In Flash esistono tutta una serie di caratteristiche volte alla sicurezza ed al controllo dell'accesso a domini differenti da quello in cui sta "girando" il nostro filmato. Tuttavia sono facilmente impostabili da codice e dipendono sostanzialmente dalle scelte dello svilupparore che ha scritto il codice. Accedere, quindi, ad un file RSS di un qualsiasi dominio è, in Flash, cosa assai semplice. Inoltre, invece di usare una pagina PHP come proxy, si può sfruttare la capacità di Javascript di comunicare con Flash e quindi usare quest'ultimo come proxy.
Un esempio di PHP proxy server per tutti
Un semplice esempio di come scrivere una pagina PHP che esegue un proxy server minimale, da me usato spesso e volentieri...
-
function getContent ( $url ) {
-
$timeout = 5; // set to zero for no timeout
-
// display file
-
return ( $file_contents );
-
}
Questa semplice funzione sfrutta proprio le curl libraries per accedere ad una pagina, che potrebbe essere, ad esempio, un XML Feed RSS. In questo modo una chiamata Ajax riceverà il risultato tramite questo semplice proxy server PHP.
Vedi anche
- How to make XMLHttpRequest calls to another server in your domain
- AJAX: Bypassing XMLHTTPRequest cross-domain restrictions
- Cross-domain XMLHttpRequest



















Giovambattista Fazioli ha detto:
Rilasciato da poco, vedi anche: Ajax Cross Domain
upnews.it ha detto:
undolog » Blog Archive » Tunneling e proxy server per Ajax e non solo…
A causa della sua capacità di comunicare con il server, l’oggetto XmlHttpRequest (XHR), usato nella tecnologia Ajax (acronimo di Asynchronous JavaScript and XML, la cui pronuncia dovrebbe essere “egiacsâ€? anche se noi italiani preferiamo “aiacs…
Napolux ha detto:
Ottimo articolo, me lo “deliciousizzo” al volo
Very short trick: proxy RSS con SimplePie | Undolog.com ha detto:
[...] dotarvi di un proxy (tunneling) a causa delle protezioni imposte da entrambe le tecnologie (vedi Tunneling e proxy server per Ajax e non solo ). Se sul vostro sito o blog è già presente SimplePie, potete scrivere una semplice proxy in [...]