Indice del forum Olimpo Informatico
I Forum di Zeus News
Leggi la newsletter gratuita - Attiva il Menu compatto
 
 FAQFAQ   CercaCerca   Lista utentiLista utenti   GruppiGruppi   RegistratiRegistrati 
 ProfiloProfilo   Messaggi privatiMessaggi privati   Log inLog in 

    Newsletter RSS Facebook Twitter Contatti Ricerca
* Chiamate ajax extradominio con un proxy php
Nuovo argomento   Rispondi    Indice del forum -> Linguaggi per Internet
Precedente :: Successivo  
Autore Messaggio
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 16 Giu 2008 00:08    Oggetto: * Chiamate ajax extradominio con un proxy php Rispondi citando

Salve forum,
sono qui a scrivere in questa serata semi-tempestosa per mostrarvi come effettuare chiamate ajax extra-dominio.
Concettualmente il problema è il seguente: "Non è possibile, per questioni di sicurezza, fare una chiamata ajax ad una pagina che si trova in un dominio diverso da quello in cui lo script javascript gira".
Per risolvere il problema scriverò un piccolo proxy in php. Questo script servirà da interfaccia tra il vostro script ajax e la pagina extra-dominio che vorrete chiamare.
Nell'esempio qui sotto faremo una paginetta html con un div che conterrà il risultato di una ricerca tramite google.

La pagina html è la seguente:
Codice:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test php proxy</title>
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript" src="callGoogle.js"></script>
</head>
<body>
   <form name="Frm" method="get" action="">
      Query:&nbsp;<input type="text" id="txtQuery" value="">&nbsp;
      <input type="button" id="btnGo" value="Vai" onClick="callGoogle(document.getElementById('txtQuery').value);">
   </form>
   <br/>
   Risultato:
   <div align="center">
      <div id="idOutput" style="width:1000px; height:480px; overflow: auto; border:solid 1px; text-align:justify; ">
      </div>
   </div>
</body>
</html>

Come potete vedere è una paginetta semplice semplice.
Essa richiama due js:
- ajax.js che contiene la funzione per allocare l'oggetto xmlHttpRequest. E' un'implementazione che ho usato un po' di tempo fa in un programma.
- callGoogle.js che contiene le funzioni ajax che chiameranno google.
In questa versione non faremo uso del proxy quindi quello che otterremo sarà un messaggio di errore.

Il codice ajax.js è il seguente e sarà lo stesso anche nell'esempio successivo
Codice:

/*
                                       - ObjXMLHttpRequest.js -
   Serve a gestire la creazione dell'oggetto XMLHttpRequest.
   Versione: 2007.03.08
*/

/*
   XMLHttp.
   Conterrà l'istanza dell'oggetto XMLHttpRequestObject.
*/
var XMLHttp = CreateXMLHttpRequestObject();

/*
   Le 5 var che seguono sono costanti che rappresentano gli stati
   della richiesta.
   XHS sta per: Xml Html Status
*/
var XHS_UNINIT      = 0;   // Uninitialized
var XHS_LOADING      = 1;   // Loading
var XHS_LOADED      = 2;   // Loaded
var XHS_INTER      = 3;   // Interactive
var XHS_COMPLETE   = 4;   // Complete

/*
   CreateXMLHttpRequestObject().
   Funzione per creare l'istanza di XMLHttpRequest.
   
   Parametri Ricevuti:
      Nessuno
   
   Valori Ritornati:
      false:
         In caso di errore.
      l'istanza di XMLHttpRequest:
         In caso di successo
*/
function CreateXMLHttpRequestObject()
{
   var XMLHttp = false;
   
/*
   Provo a creare l'istanza ipotizzando un browser diverso da IE6 o precedente.
   Nel caso scatti, gestisco l'eccezione e provo con la famiglia IE6 o precedente.
   Non provo subito con IE perch� IE7 usa l'oggetto XMLHttpRequest come gli altri browser
   oppure come activex e quindi se si pu�, evito l'activex.
*/
   try
   {
      XMLHttp = new XMLHttpRequest();
   }
   catch(e)
   {
   // Elenco dei possibili Prog ID
      var XMLHttpVers = new Array
      (
         'MSXML2.XMLHTTP.6.0',
         'MSXML2.XMLHTTP.5.0',
         'MSXML2.XMLHTTP.4.0',
         'MSXML2.XMLHTTP.3.0',
         'MSXML2.XMLHTTP',
         'Microsoft.XMLHTTP'
         
      );
   //  Cerco il Prog ID corretto
      for (var i=0;i<XMLHttpVers.length;++i)
      {
         try
         {
            XMLHttp = new ActiveXObject(XMLHttpVers[i]);
         }
         catch(e)   // Devo ignorare gli errori
         {
         }
      }
   }

   
   if (!XMLHttp)
      alert("L'oggetto XMLHttpRequest non può essere creato!");
   else
      return XMLHttp;
}

mentre lo script callGoogle.js è:
Codice:

var idOutput = '';   // contenitore dei risultati

function callGoogle(query)
{   
   idOutput=document.getElementById('idOutput');
   
   if (XMLHttp)
   {
      try
      {
         if (XMLHttp.readyState==XHS_COMPLETE || XMLHttp.readyState==XHS_UNINIT)
         {
            var q=encodeURIComponent(query);
            var queryString
               = 'q=' + q;
               
            var url = 'http://www.google.it';
            
            XMLHttp.open('POST',url + '?' + queryString,true);   
            XMLHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            XMLHttp.onreadystatechange=callGoogle_StateChange;
            XMLHttp.send();
         }
      }
      catch(e)
      {
         idOutput.innerHTML='Errore: ' + e.toString();
      }
   }
}

function callGoogle_StateChange()
{
   if (XMLHttp.readyState==XHS_COMPLETE)
   {
      if (XMLHttp.status==200)
      {   
         try
         {
            callGoogle_Response();
         }
         catch(e)
         {
            idOutput.innerHTML='Errore: ' + e.toString();
         }   
      }
      else
      {
         idOutput.innerHTML='Errore: ' + XMLHttp.statusText;
      }
   }
}

function callGoogle_Response()
{
// leggo il testo della pagina
   var resp=XMLHttp.responseText;

// Creo l'output   
   idOutput.innerHTML=resp;
}

Se provate ad eseguire una ricerca avrete il seguente messaggio di errore:
Codice:

Errore: Permesso negato al metodo di chiamata XMLHttpRequest.open

Questo avviene perchè facciamo una chiamata ad una pagina fuori dal nostro dominio.

Le librerie curl permettono di fare tante cose tra cui chiamare una pagina con dei parametri, possiamo settare gli headers come vogliamo e tantissime altre cose.

L'esempio successivo spiega come fare per "proxare" le chiamate.
La pagina html e lo script ajax.js sono gli stessi, quindi non li ri-riporto.
Dobbiamo creare una pagina phpProxy.php che implementerà il nostro proxy:
Codice:

<?php
/**
 * Proxy php basato sulla libreria curl (ovviamente è richiesta)
 *
 * Lo scopo è quello di proxare le chiamate a pagine extra-dominio da parte di funzioni ajax.
 *
 * Utilizzo:
 * Lo script riceve i seguenti parametri:
 * u: indirizzo della pagina con relativa querystring "encodata"
 * h: "true" se si vuole che vengano ritornati gli headers della pagina chiamata; "false" altrimenti (default)
 * m: mimeType desiderato
 *
 * L'unico parametro obbligatorio è 'u'
 *
 * Note:
 * Il codice riportato prende spunto da PHP Proxy di Abdul Qabiz
 */

// Se non è settato il parametro 'u' fermo tutto e segnalo l'errore.
   $url='';
   if (!isset($_REQUEST['u']))
   {
      print 'Occorre impostare il parametro "u"!';
      exit;
   }
   $url = $_REQUEST['u'];
   
// Decido come gestire gli headers della pagina chiamata
   $headers='false';
   if (isset($_REQUEST['h']))
   {
      switch($_REQUEST['h'])
      {
         case 'true':
            $headers=true;
            break;
         case 'false':
            $headers=false;
            break;
         default:
            print 'Valore non previsto per il parametro "h"!';
            exit;
      }
   }

// Decido il mimetype
   $mimeType=null;
   
   if (isset($_REQUEST['m']))
      $mimeType=$_REQUEST['m'];
      
// Inizializzo la sessione curl
   $ses = curl_init($url);
   
// Se lo script viene chiamato con una post dovrò salvare le vars "postate"
   if ($_POST['u'])
   {
      $vars='';
      while($p=current($_POST))
      {
         $vars.=key($_POST) .'=' . $p . '&';
         next($_POST);
      }
      
      curl_setopt ($ses, CURLOPT_POST, true);
      curl_setopt ($ses, CURLOPT_POSTFIELDS, $postvars);
   }
   
// Imposto la gestione degli headers
   curl_setopt($session, CURLOPT_HEADER, $headers);
   
// Altre opzioni: rimando alla documentazione di curl
   curl_setopt($session, CURLOPT_FOLLOWLOCATION, true); 
   curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
   
// chiamo la pagina
   $response = curl_exec($ses);
   
// se è  il caso setto l'header
   if ($mimeType != null)
   {
      header("Content-Type: " . $mimeType);
   }
   
// ritorno l'output
   print $response;
   
// Chiudo la sessione
   curl_close($ses);
?>

nello script ci sono dei commenti che dovrebbero chiarire le varie fasi. Per domande postate qui.
Dobbiamo modificare la funzione callGoogle(...) affinchè chiami il proxy e che dica a questo di mandare la querystring a google:
Codice:

function callGoogle(query)
{   
   idOutput=document.getElementById('idOutput');
   
   if (XMLHttp)
   {
      try
      {
         if (XMLHttp.readyState==XHS_COMPLETE || XMLHttp.readyState==XHS_UNINIT)
         {
            var q=encodeURIComponent(query);
            var queryString
               = 'q=' + q;
               
            var url='http://prove/phpproxy/phpProxy.php?u=' + encodeURIComponent('http://www.google.it/search?' + queryString)
            
            XMLHttp.open('GET',url,true);
            XMLHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            XMLHttp.onreadystatechange=callGoogle_StateChange;
            XMLHttp.send();
         }
      }
      catch(e)
      {
         idOutput.innerHTML='Errore: ' + e.toString();
      }
   }
}

Usando questa versione riusciremo a fare la chiamata ajax a google e nel box visualizzeremo i risultati.
Faccio notare alcune cose:
1) fuori dal box vedremo apparire una rigaccia: è per come è fatta la pagina di google.
2) non riusciremo ad usare l'impaginatore dei risultati di google: anche questo è per il modo in cui è scritto google.

Qualche link che tratta le cose scritte in questo post:
Libreria curl:
link

Chiamate ajax extradominio
link
link

Script da cui ho tratto il proxy
link

Come al solito spero di essere di aiuto a qualcuno qui nel forum.

Saluti a tutti


L'ultima modifica di freemind il 15 Mar 2010 23:54, modificato 1 volta
Top
Profilo Invia messaggio privato
mdweb
Dio maturo
Dio maturo


Registrato: 18/12/07 16:59
Messaggi: 4412

MessaggioInviato: 16 Giu 2008 10:03    Oggetto: Rispondi citando

Interessantissimo Very Happy Laughing Laughing
Top
Profilo Invia messaggio privato
peroncina
Comune mortale
Comune mortale


Registrato: 17/10/08 15:14
Messaggi: 3

MessaggioInviato: 04 Nov 2008 15:16    Oggetto: Rispondi citando

ho visto questo articolo è avrei bisogno di delucidazioni...
sto sviluppando un'estensione su google calendar, dovrei caricare tutto il feed di google calendar pubblico con una chiamata di XMLHttpRequest e poi dovrei ricavare gli elementi che voglio visualizzare in base a certi criteri (per esempio solo gli eventi del giorno e della settimana) e una volta fatto questo li uso per popolare un popup o una pagina.
come posso fare? posso utilizzare questa guida? mi aiuteresti?
Top
Profilo Invia messaggio privato
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 05 Nov 2008 19:05    Oggetto: Rispondi citando

Ciao,
se non mi ricordo male tu stai sviluppando un'estensione per FF, giusto?
Io mi ero imbattuto nel problema di fare chiamate ajax da un widget per opera; visto che però in due o tre tentativi non son riuscito e dato che era solo per curiosità, ho lasciato perdere.
Il problema di fondo è che questo proxy funziona ma ha bisogno di un web-server! Senza, lo script php non gira e quindi ciao ciao proxy!
Se tu sei già in grado di eseguire una chiamata extra-dominio verso google calendar, posso provare a darti una mano a manipolare il feed che ti arriva; se neppure la chiamata ti riesce, beh, ci tocca scoprire come farla!

Se hai qualche idea, posta qui che vediamo un po' che si può fare.
Non potrò dedicarti moltissimo tempo, anzi, a dire il vero ne ho proprio poco ma qualche risposta dovrei riuscire a scriverla.

Ciao ciao
Top
Profilo Invia messaggio privato
kappah
Comune mortale
Comune mortale


Registrato: 25/11/08 10:58
Messaggi: 1

MessaggioInviato: 26 Nov 2008 11:05    Oggetto: Rispondi citando

Ho letto questa discussione e provato ad implementare un mio progetto con il php proxy. Purtroppo non riesco a farlo funzionare.

Ho un file .js che invia una richiesta tramite ajax ad un programma in c sul server. Questo è il file .js:

Codice:
init_eyeProvaCalcolo($myPid,$checknum);

function init_eyeProvaCalcolo(myPid,checknum) {

   var stringa="";
   
   //Numeri
   for(i=0;i<10;i++) {
   //   eval('document.getElementById("'+myPid+'_bttn'+i+'").onclick = function(event) {showMsg('+i+');};');
   eval('document.getElementById("'+myPid+'_bttn'+i+'").onclick = function(event) {showMsg('+vett['id'+i+'']+');};');
   }
   

   //Operazioni
   var bttnDivide = document.getElementById(myPid+'_bttn/');
   var bttnMultiply = document.getElementById(myPid+'_bttn*');
   var bttnSubstract = document.getElementById(myPid+'_bttn-');
   var bttnAdd = document.getElementById(myPid+'_bttn+');
   var bttnBack = document.getElementById(myPid+'_bttnBack');
   
   //Speciali
   var bttnCe = document.getElementById(myPid+'_bttnCE');
   var bttnC = document.getElementById(myPid+'_bttnC');
   var bttnMc = document.getElementById(myPid+'_bttnMC');
   var bttnRad = document.getElementById(myPid+'_bttnsqrt');
   var bttnMr = document.getElementById(myPid+'_bttnMR');
   var bttnPercent = document.getElementById(myPid+'_bttn%');
   var bttnMs = document.getElementById(myPid+'_bttnMS');
   var bttnUnderx = document.getElementById(myPid+'_bttn1/x');
   var bttnMAdd = document.getElementById(myPid+'_bttnM+');
   var bttnSign = document.getElementById(myPid+'_bttn+/-');


   //Simboli
   var bttnDot = document.getElementById(myPid+'_bttn.');
   var bttnEqual = document.getElementById(myPid+'_bttn=');
   
  bttnEqual.onclick = function() {showMsg(vett['idEqual']);};
   bttnDot.onclick = function() {showMsg(vett['idPoint']);};
   bttnDivide.onclick = function() {showMsg(vett['idDivide']);};
   bttnMultiply.onclick = function() {showMsg(vett['idMultiply']);};
   bttnSubstract.onclick = function() {showMsg(vett['idSubstract']);};
   bttnAdd.onclick = function() {showMsg(vett['idAdd']);};
   bttnBack.onclick = function() {showMsg(vett['idBack']);};
   bttnCe.onclick = function() {showMsg(vett['idCE']);};
   bttnC.onclick = function() {showMsg(vett['idC']);};
   bttnMc.onclick = function() {showMsg(vett['idMC']);};
   bttnRad.onclick = function() {showMsg(vett['idSqrt']);};
   bttnMr.onclick = function() {showMsg(vett['idMR']);};
   bttnPercent.onclick = function() {showMsg(vett['idPercentage']);};
   bttnMs.onclick = function() {showMsg(vett['idMS']);};
   bttnUnderx.onclick = function() {showMsg(vett['idInv']);};
   bttnMAdd.onclick = function() {showMsg(vett['idM+']);};
   bttnSign.onclick = function() {showMsg(vett['idSign']);};
   
   function test(id){
      var myArray;
      myArray = id;
      alert(id);
   }
   
   
   function PreparaDati(button){
      
      var str=String(button);
      
      //if (str.length==1) stringa="000"+button;
      //else if (str.length==2)   stringa="00"+button;
      //else if (str.length==3) stringa="0"+button;
      
      stringa = 'v=' + 'CLCK';
   
   }
   
   function AJAXReq(method,url,bool){
  if(window.XMLHttpRequest){
    myReq = new XMLHttpRequest();
  } else
 
  if(window.ActiveXObject){
    myReq = new ActiveXObject("Microsoft.XMLHTTP");
   
    if(!myReq){
      myReq = new ActiveXObject("Msxml2.XMLHTTP");
    }
  }
 
  if(myReq){
    execfunc(method,url,bool);
  }else{
    alert("Impossibilitati ad usare AJAX");
  }
}
function execfunc(method,url,bool){
  myReq.onreadystatechange = function() { handleResponse(myReq); };
  myReq.open(method,url,bool);
  myReq.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
  myReq.send(null);
}

function handleResponse(myReq){
  if(myReq.readyState == 4){
    if(myReq.status == 200){
       alert(myReq.responseText);
    }else{
      alert("Niente da fare, AJAX non funziona :");
    }
  }
}

   
   function showMsg(button) {
      PreparaDati(button);
    AJAXReq('GET','http://localhost/phpProxy.php?u=' + encodeURIComponent('http://130.192.76.228:20000?' + stringa),true);
}

}


Questo invece è il file .php del proxy:


Codice:
<?php
/**
 * Proxy php basato sulla libreria curl (ovviamente è richiesta)
 *
 * Lo scopo è quello di proxare le chiamate a pagine extra-dominio da parte di funzioni ajax.
 *
 * Utilizzo:
 * Lo script riceve i seguenti parametri:
 * u: indirizzo della pagina con relativa querystring "encodata"
 * h: "true" se si vuole che vengano ritornati gli headers della pagina chiamata; "false" altrimenti (default)
 * m: mimeType desiderato
 *
 * L'unico parametro obbligatorio è 'u'
 *
 * Note:
 * Il codice riportato prende spunto da PHP Proxy di Abdul Qabiz
 */

// Se non è settato il parametro 'u' fermo tutto e segnalo l'errore.
   $url='';
   if (!isset($_REQUEST['u']))
   {
      print 'Occorre impostare il parametro "u"!';
      exit;
   }
   $url = $_REQUEST['u'];
   
// Decido come gestire gli headers della pagina chiamata
   $headers='false';
   if (isset($_REQUEST['h']))
   {
      switch($_REQUEST['h'])
      {
         case 'true':
            $headers=true;
            break;
         case 'false':
            $headers=false;
            break;
         default:
            print 'Valore non previsto per il parametro "h"!';
            exit;
      }
   }

// Decido il mimetype
   $mimeType=null;
   
   if (isset($_REQUEST['m']))
      $mimeType=$_REQUEST['m'];
     
// Inizializzo la sessione curl
   $ses = curl_init($url);
   
// Se lo script viene chiamato con una post dovrò salvare le vars "postate"
   if ($_POST['u'])
   {
      $vars='';
      while($p=current($_POST))
      {
         $vars.=key($_POST) .'=' . $p . '&';
         next($_POST);
      }
     
      curl_setopt ($ses, CURLOPT_POST, true);
      curl_setopt ($ses, CURLOPT_POSTFIELDS, $postvars);
   }
   
// Imposto la gestione degli headers
   curl_setopt($session, CURLOPT_HEADER, $headers);
   
// Altre opzioni: rimando alla documentazione di curl
   curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
   curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
   
// chiamo la pagina
   $response = curl_exec($ses);
   
// se è  il caso setto l'header
   if ($mimeType != null)
   {
      header("Content-Type: " . $mimeType);
   }
   
// ritorno l'output
   print $response;
   
// Chiudo la sessione
   curl_close($ses);
?>


Il messaggio d'errore ke mi viene fuori è il seguente:

Access to restricted URI denied" code: "1012

Se invece dell'ip metto il nome del mio server web in questo modo:

AJAXReq('GET','http://kappah.dnsalias.com/phpProxy.php?u=' + encodeURIComponent('http://kappah.dnsalias.com:20000?' + stringa),true);

la cosa funziona. E' giusto così ho sbaglio qualkosa??

Se riesci a darmi una mano mi faresti un grosso favore....Thanks!
Top
Profilo Invia messaggio privato
SolidSnake4
Comune mortale
Comune mortale


Registrato: 10/03/10 13:19
Messaggi: 1

MessaggioInviato: 10 Mar 2010 13:26    Oggetto: Rispondi citando

salve io vorrei usare questo script per far visualizzare gli annunci google adsense, in quanto ora come ora mi da problemi sulla visualizzazione e con firebug mi esce l'errore permesso negato al metodo di chiamata e in pratica non mi fa visualizzare gli altri annunci. Siccome non sono molto pratico di ajax, cosa dovrei modificare in questo script ?
Top
Profilo Invia messaggio privato
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 11 Mar 2010 20:29    Oggetto: Rispondi

Ciao,
il proxy php non va toccato (almeno per ora); bisogna invece modificare la funzione callGoogle.

Devi cambiare il div di destinazione dell'output, ossia quello che è puntatao dalla var idOutput; tu dovrai avere un div che conterrà la pubblicità.

Poi modifichi la variabile url usando l'indirizzo che devi chiamare per visualizzare la pubblicità.

Questo penso che basti se non altro per eliminare l'errore di permesso negato.
Top
Profilo Invia messaggio privato
Mostra prima i messaggi di:   
Nuovo argomento   Rispondi    Indice del forum -> Linguaggi per Internet Tutti i fusi orari sono GMT + 2 ore
Pagina 1 di 1

 
Vai a:  
Non puoi inserire nuovi argomenti
Non puoi rispondere a nessun argomento
Non puoi modificare i tuoi messaggi
Non puoi cancellare i tuoi messaggi
Non puoi votare nei sondaggi