Newsgroup: it.comp.lang.javascript
Titolo: XmlHttpRequest e PHP

Torno sull'argomento perché ormai mi ci voglio divertire (come dicevo
qualche post fa), dunque ho questa pagina (presa da Cristiano Larghi che
ringrazio):
function getXmlHttpRequest(){
	if (window.ActiveXObject) {
		/*@cc_on
		@if (@_win32)
     			return new ActiveXObject("Microsoft.XMLHTTP");
	  	@end 
		@*/
		return null;
	} else if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else {
		return null;
	}
 
} //getxmlHttpRequest
 
function getXmlDocument(s) {
	if (typeof DOMParser=="object") {
		return new DOMParser().parseFromString(s, 'text/xml');
	} else if (window.ActiveXObject) {
		var xmldoc=new ActiveXObject("Microsoft.XMLDOM");
		xmldoc.loadXML(s);
		return xmldoc;
	} else {
		return s;
	}
}
function TestPwd(password) {
	var xmlDOM=getXmlHttpRequest();
	if (!xmlDOM) {
		alert("questo browser non supporta XmlHttp!");
		return false;
	}
	//xml per parametri
	var
Parametri="<request><password><![CDATA["+password+"]]></password></request>";
	xmlDocument=getXmlDocument(Parametri);
	xmlDOM.open("POST","XmlHttpServer.php",false);
 
	//per evitare bug mozilla
	if (typeof xmlDOM.setRequestHeader=='function') {
		xmlDOM.setRequestHeader('Connection','Close');
	}
 
	//invio parametri
	xmlDOM.send(xmlDocument);
	var xmlDOC=xmlDOM.responseXML;
	alert(xmlDOC.xml);
}
Poi ho XmlHttpServer.php che scrive solamente:
<?php
header ("Content-Type: text/xml");
echo "<RESPONSE>"+$_POST+"</RESPONSE>";
?>
Però Firefox mi da undefined, Explorer invece apre un alert vuoto. Che ho
fatto di male?
Luke S.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 echo "<RESPONSE>"+$_POST+"</RESPONSE>";
Dunque...$_POST è l'array passato via post, cosa restituisce php
richiedendo l'intero array? Prova a indicare che è un valore testuale:
echo "<RESPONSE><![CDATA["+$_POST+"]]></RESPONSE>";
(sto ragionando in astratto perché non so nulla di php)
-- 
"Non sai che ci vuol scienza
 ci vuol costanza
 ad invecchiare senza maturità"
									    F.G.

 Zer0 (soprattutto per la compilazione condizionale per IE5-mac)
:) Se ben ricordo ti passai proprio la function; solo in un secondo tempo
la modificai sul NG per IE/Mac (perché esponeva ActiveXObject senza
supportarlo).
-- 
~ Se cerchi una mano disposta ad aiutarti,
la trovi alla fine del tuo braccio.

 Poi ho XmlHttpServer.php che scrive solamente:
A questo punto, in XmlHttpServer.php puoi benissimo fare:
<?php
	if ($_POST["password"] == "pluto"){
		echo "allowed";	
	}else{
		echo "not allowed";
	}
?>
Dovrebbe andare tutto, l'ho scritto al volo, ma cmq il concetto è questo.
Il fatto che si possa utilizzare, in input e in output, un XML è un gran
vantaggio, ma non è detto che si debba sempre fare.
-- 
~ Non sono disordinato. Sono solo un massimizzatore di entropia.

 (sto ragionando in astratto perché non so nulla di php)
Sě $_POST č l'array, dovrebbe scrivere a video Array. Il Cdata non
andrebbe neanche messo, per quello che ne so io, in un file XML il testo
dei nodi non va riportato tra sezioni Cdata. Comunque l'ho provato e non
va :(
Ho tentato a fare tutto diversamente, cioč non passare e ricevere un file
XML, ma passare e ricevere dei semplici parametri (GET o POST), cosě:
xmlhttp.open("GET", "nomeFile.php?parametro=" + escape(varParametro),
true);
xmlhttp.onreadystatechange = funzioneCheRecuperaIDati;
xmlhttp.send(null);
Di la' con PHP riprendo il dato semplicemente con $_GET["parametro"]. La
stessa cosa con POST, solo che passo i parametri nel send() e con PHP li
ripesco attraverso $_POST["parametro"]. Come ho fatto io funziona, ma
vorrei capire la differenza tra il mio sistema e il tuo.
Cosa cambia nel "mio" modo di fare con quello proposto da te? (mio č
virgolettato perché č basato su ciň che ho letto in giro)
Per esempio io nella funzione "funzioneCheRecuperaIDati()" utilizzo il
readyState per verificare che sia tornato il valore, mentre la tua
proposta non lo fa, scrivendo subito:
var xmlDOC=xmlDOM.responseXML;
alert(xmlDOC.xml);
Altra domanda, nel metodo open() il terzo parametro indica se la chiamata
va fatta asincrona (true) o sincrona (false). Che cambia?
Ti ringrazio ancora per il tempo dedicatomi :-))


 vantaggio, ma non è detto che si debba sempre fare.
Esatto, quando consiglieresti l'utilizzo di XML? quando è importante
passare e ricevere dati con una certa semantica? Invece di:
parametro=valore&parametro2=valore2&parametro3=valore3
Ma magari avere:
<?xml version="1.0"?>
<esempio>
<xmlhttprequest method="post" valori="xml">E' proprio una
figata</xmlhttprequest>
</esempio>


 va fatta asincrona (true) o sincrona (false). Che cambia?
asincrona non attende che il server restituisca il valore di ritorno (e
quindi occorre creare function da scatenare nell'evento onreadystatechange,
io non lo ho mai usato in questo modo), sincrona invece ferma l'esecuzione
dello script e attende che il server restituisca un valore di ritorno.
-- 
"E' l' ignoranza che crea l'intolleranza
 di gente cieca e senza coscienza"
									  S.S.S.

 passare e ricevere dati con una certa semantica? 
Se i dati da inviare sono effettivamente complessi a livello strutturale.
Ad esempio sono gerarchici, e la gerarchia č fondamentale per l'utilizzo
dei dati stessi.
Oppure, se i dati che vengono restituiti da PHP, non servono solo alla tua
applicazione. In questo modo, veicolandoli tramite XML sono fruibili a
qualsiasi altra applicazione scritta in qualsiasi altro linguaggio.
Ma come ti ho detto, non c'č un "regola".
-- 
~ Il futuro č nelle nostre mani.
Purtroppo.

 Cosa cambia nel "mio" modo di fare con quello proposto da te? 
Invii dei dati come si trattasse di una form, invece di inviare un
documento XML.
-- 
~ "FINARMENTE LI SFRATTATI AVRANNO UN TETTO SULLA TESTA!
...però tirato ammodino, un tegolo pe' vorta.." (Il vernacoliere)

 nell'altro post.
Ho provato con:
xmlhttp.open("GET", "nomeFile_get.php", true);
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlhttp.onreadystatechange = funzioneCheGestisceIlRitorno;
 
if (typeof xmlhttp.setRequestHeader=='function') {
	xmlhttp.setRequestHeader('Connection','Close');
}
xmlhttp.send("parametro=" + escape(valore));
Ma non funziona. C'è qualcosa che non va che puoi dirmi al volo?


 	$GLOBALS['HTTP_RAW_POST_DATA']
Ho provato a ripescarli con questo, ma l'alert su explorer è vuoto e su
firefox è undefined :-(


 Ma non funziona. 
"Non funziona", non vuol dire molto. La javascript console che cosa ti
dice?
-- 
~ Il lavoro č prezioso. Non essere egoista! Lascialo agli altri!

 Ho provato a ripescarli con questo, 
Non devi "ripescare" nulla, quella è una stringa. In questa variabile hai i
dati grezzi inviati dal browser. Per farti un esempio veloce, usando un
solo file php:
<?php
if ( $_SERVER["REQUEST_METHOD"] == "POST" ){
	header("Content-Type:text/xml");
	die($GLOBALS['HTTP_RAW_POST_DATA']);
}
?>
<script type="text/javascript">
 
	var xmlhttp=new XMLHttpRequest();
	function f(){
		var doc = new DOMParser().parseFromString("<req attr=\"a
value\">description..</req>","text/xml");
 
		xmlhttp.open("POST" ,"test.php",false);
		xmlhttp.setRequestHeader('Connection','Close');
		xmlhttp.send(doc);
		alert(xmlhttp.responseXML.documentElement.getAttribute("attr"));
	}
</script>
<button onclick="f()">click me</button>
Questo non fa altro che far "rimbalzare" il medesimo documento da client a
server, coprendo quindi le due casistiche (scritto per FF, ti basta
sostituire la creazione del document e del request con le funzion
crossbrowser e sei a posto anche su IE).
-- 
~ Un computer e' fondamentalmente stupido.
Non fa cio' che vuoi che faccia, ma cio' che gli dici di fare.

 dice?
Sě scusami, dunque la console js non dice nulla, in pratica č come se non
passasse il parametro. Ora sto facendo:
var valore = document.getElementById("valore").value;
xmlhttp.open("GET", "file.php", true);
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlhttp.onreadystatechange = gestisciRisposta;
 
if (typeof xmlhttp.setRequestHeader=='function') {
	xmlhttp.setRequestHeader('Connection','Close');
}
xmlhttp.send("param=" + escape(valore));
return false; // arrivo da un onsubmit
in file.php ho semplicemente: echo $_GET["param"];
nella funzione gestisciRisposta() invece ho:
if (xmlhttp.readyState == 4) {
	results = xmlhttp.responseText;
 
	if (xmlhttp.status == 200) {
		alert(results);
	} else {
		alert("Si sono verificati dei problemi lato server:\n" +
xmlhttp.statusText);
	}
 
}
e l'alert (alert(results)) č vuoto, evidentemente il file .php non riceve
nulla. trovi qualcosa che non va?


 nella funzione gestisciRisposta() invece ho:
Eliminala, e prova prima a far funzionare tutto in modo sincrono.
-- 
~ Always remember you're unique, just like everyone else.

 alert(xmlhttp.responseXML.documentElement.getAttribute("attr"));
Ho capito, ho però l'ultimo dubbio, su explorer funziona, ma su firefox da
undefined, il punto incriminato è:
alert(xmlDOC.xml);
xmlDOC è:
var xmlDOC=xmlDOM.responseXML;
e xmlDOM è:
var xmlDOM=getXmlHttpRequest();
In pratica l'esempio preso da 
criosoftware.it
, come mai firefox mi da
undefined?


 In pratica l'esempio preso da 
criosoftware.it
, 
Dubito che nell'esempio di cristiano sia presente l'uso di .xml in uno
script definito come crossbrowser.
-- 
~ Chi segue gli altri, non arriva mai primo.

 Eliminala, e prova prima a far funzionare tutto in modo sincrono.
Ok ho seguito i tuoi consigli e ora ho lo scheletro (fico cosě, avevi
ragione ;-)
<script type="text/Javascript">
// <![CDATA[
function verifica() {
	var http = getHTTPObject();
	http.open("GET", "file.php", false);
	http.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
 
	if (typeof http.setRequestHeader=='function') {
		http.setRequestHeader('Connection','Close');
	}
	http.send("param=valore");
 
	alert(http.responseText);
}
function getHTTPObject() {
	if (window.ActiveXObject) {
		/*@cc_on
		@if (@_win32)
     			return new ActiveXObject("Microsoft.XMLHTTP");
	  	@end 
		@*/
		return null;
	} else if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else {
		return null;
	}
 
}
// ]]>
</script>
<button onclick="verifica()">verifica</button>
nel file PHP poi ho:
<?php
echo "valore: ".$_GET["param"];
?>
Ma l'alert risultante da solo valore: senza leggere il parametro passato
via GET. Come mai č vuoto?


 	}
Non ha senso che controllo qui la function. O la controlli prima di
impostare il content type, oppure non la controlli affatto.
-- 
~ "Quando i morti camminano, signori, bisogna smettere di uccidere.
O si perde la guerra." (Zombie)

 script definito come crossbrowser.
Scusa ma non me lo sono inventato, nell'esempio .zip che si scarica da
criosoftware.it
 la funzione č:
 function TestPwd(password) {
  var xmlDOM=getXmlHttpRequest();
  if(!xmlDOM) {
   alert("questo browser non supporta XmlHttp!");
   return false;
  }
  //xml per parametri
  var
Parametri="<request><password><![CDATA["+password+"]]></password></request>";
  xmlDocument=getXmlDocument(Parametri);
  xmlDOM.open("POST","XmlHttpServer.asp",false);
  //per evitare bug mozilla
  if(typeof xmlDOM.setRequestHeader=='function')
   xmlDOM.setRequestHeader('Connection','Close');
  //invio parametri
  xmlDOM.send(xmlDocument);
  var xmlDOC=xmlDOM.responseXML;
  alert(xmlDOC.xml);
 }
Ora so che .xml non va usato, cosa utilizzo per visualizzare tutto l'xml
restituito? con xmlDOC mi restituisce [object XMLDocument].
nota: ora che controllo meglio su
http://www.criosoftware.it/default39.aspx
 c'č alert(xmlDOC), mentre nel
zip che ho scaricato, il file .htm presenta alert(xmlDOC.xml) - e io da
qui lavoravo. Consiglio a Cristiano di correggerlo, altrimenti qualcun
altro puņ incontrare l'errore...


 POST e poi hai mischiato un po' le due cose.
Sì mi sono fatto un po' di esempi:
get asincrono
get sincrono
post asincrono
post sincrono
tutti con dati trattati come un form e funzione egregiamente (devo
ringraziare te e Cristiano per avermi chiarito le idee).
ora mi manca solo di capire un po' meglio l'invio dei dati post con però
un file xml (in pratica quel xmlDOC.xml di cui parliamo qualche msg
sotto). e naturalmente devo capire come PHP gestisce i file xml (anzi,
l'albero xml che arriva via post), ma quello penso di trovarlo su 
php.net
.


 restituito? 
Se ti serve per fare il "debug" di ciò che ti viene restituito dall'oggetto
XmlHttpRequest, puoi benissimo utilizzare la proprietà "responseText".
E per dover di cronaca, per recuperare in stringa un documento XML in
generale, nei browser standard esiste un oggetto, al pari di DOMParser, per
questo genere di operazioni:
alert(new XMLSerializer().serializeToString(xmlDOC) );
Ergo, avrai qualcosa tipo:
function getXmlSourceCode( doc ){
	if ( window.XMLSerializer )
		return new XMLSerializer().serializeToString( doc );
	else if (typeof doc.xml=="string")
		return doc.xml;
	else
		return null;
}
Ma è raro che ti serva recuperare di un xml l'intero contenuto in formato
stringa.
-- 
~ Confondi il mondo, sorridi tutti i lunedì!

 alert(new XMLSerializer().serializeToString(xmlDOC) );
perfetto; ti ringrazio davvero, ho le idee molto più chiare, ora non mi
resta che smanettare un po' con php per maneggiare al meglio ciò che gli
mando via xmlhttprequest.
grazie ancora.


 		xmlhttp.setRequestHeader('Connection','Close');
Scusate l'intrusione... cosa indica questo header?
-- 
Nando [?]
Ex-Apostolo della Ex-Prova

   alert(xmlDOC.xml);
ARGH !!! pardon, corretta (Avevo fatto quelle pagine in tempo reale mentre
testavo per un sito, si vede che questa era rimasta dalle function che uso
in intra. Copiaincollato getXmlSourceCode(), ovviamente :-) )
-- 
"That until there is no longer first class
And second class citizens of any nation
Until the colour of a man's skin
Is of no more significance than the colour of his eyes
Me say war"
B.M.

 Scusate l'intrusione... cosa indica questo header?
 
http://www.criosoftware.it/default39.aspx


  
http://www.criosoftware.it/default39.aspx
Ok, grazie... anche se, usandolo, alcune cose non mi funzionano e non so
perche'... ho cercato un po' su google ma non ho capito bene il significato
dell'header. Vabbe'.
