[PHP] JSONP Webservice

jspit

Lounge-Member
Fertige Webservices zu nutzen ist ja schön, aber wie baue ich einen eigenen Webservice mit JSONP auf?
Auch das ist nicht schwer. Die serverseitige Sprache PHP liefert hierfür sehr gute Unterstützung. Clientseitig wird mit Javscript auf den Webservice zugegriffen. Im Beitrag Cross-Domain AJAX mit JSONP wird das dafür notwendige Wissen vermittelt. Dieser Beitrag baut darauf auf.
Nun zur Aufgabe. Unser erster Webserver soll uns nur unsere eigene IP anzeigen und unsere Spracheinstellung im Browser. Dafür müssen wir nur unsere Objectstruktur erstellen und füllen, für das Erstellen des JSON-Strings gibt es in PHP die function json_encode. Ist der callback-Parameter vorhanden, werden noch Name und Klammern zugefügt und das Ganze ausgegeben.
PHP:
<?php
//Serverinfo JSONP
//opt. Parameter: callback=Name
error_reporting(E_ALL ^ E_NOTICE);
$ip =($_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER["REMOTE_ADDR"];
$lg = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
//echo "REMOTE_HOST: ".$SERVER["REMOTE_HOST"]."<br>";
$j['serverinfo'][0]['ip'] = $ip;
$j['serverinfo'][0]['lg'] = $lg;
$json = json_encode($j);
//Bei callback als Funktionsaufruf generieren
if(isset($_GET['callback']) && !preg_match('/[^0-9A-Za-z\.\_]/', $_GET['callback'])) {
	//zum Schutz vor cross-site-scripting nur Zeichen fuer js_namen und . zulassen
	$json = $_GET['callback']."(".$json.");";
}
echo $json;
?>

Um dies zu testen geben wir im Browser folgendes ein:
http: //localhost/ajax/serverinfojsonp.php?callback=myfkt
und sollten so eine Antwort erhalten:
myfkt({"serverinfo":[{"ip":"127.0.0.1","lg":"de-de,de;q=0.8,en;q=0.5,en-us;q=0.3"}]});

Die eigene js-Funktion zum Verarbeiten der Information im Client muß auf die Objectstruktur der Serverantwort zugeschnitten sein. Wer mit den Objecten in Javasript noch nicht so sicher ist, kann mit dem
Javscript Online Tool
bequem solche Objecte auflisten. Im link sind schon 2 Zeilen enthalten, nachdem unsere Antwort vom Server dort reinkopiert wurde ergibt sich etwa folgendes Bild:
Code:
function myfkt(p){obj=p};
myfkt({"serverinfo":[{"ip":"127.0.0.1","lg":"de-de,de;q=0.8,en;q=0.5,en-us;q=0.3"}]});
obj
Mit dem Button Run wird jetzt das obj gezeigt. Schrittweise können wir uns jetzt durchhangeln,
indem wir obj ergänzen bis wir die gewünschte Information sehen:

Code:
Code			      Objectlist/Value
---------------------------------------------------------------------------
obj			        serverinfo: [object Object] (type=object)
obj.serverinfo		0: [object Object] (type=object)
obj.serverinfo[0]	ip: 127.0.0.1 (type=string)
			        lg: de-de,de;q=0.8,en;q=0.5,en-us;q=0.3 (type=string)
obj.serverinfo[0].ip	127.0.0.1
obj.serverinfo[0].lg	de-de,de;q=0.8,en;q=0.5,en-us;q=0.3

Wir wissen jetzt wie zugegriffen wird und können unsere eigene Function schreiben:
PHP:
function myfkt(obj) {
	var mydiv=document.getElementById("resp");
	var s = "";
    if(obj && obj.serverinfo) {
        if(obj.serverinfo[0] && obj.serverinfo[0].ip) s += "IP: " + obj.serverinfo[0].ip +  "<br>Sprachen: " + obj.serverinfo[0].lg;
        else s += "nichts gefunden";
    }
    else {
        if(obj && obj.status) s += obj.status.message;
        else s += "unbekannte Antwort";
    }
	mydiv.innerHTML = s;
}
Da nur ein Parameter callback benötigt wird, kann unsere function jsonp ohne zusätzliche Parameter aufgerufen werden:
PHP:
var nr =jsonp('http://localhost/ajax/serverinfojsonp.php?callback=?', myfkt);

Ohne Parameter wird von unseren Webservice ein JSON-Object geliefert. Das testen wir wieder über die Browserzeile:
http: //localhost/ajax/serverinfojsonp.php
und erhalten als Beispiel
{"serverinfo":[{"ip":"127.0.0.1","lg":"de-de,de;q=0.8,en;q=0.5,en-us;q=0.3"}]}

Diese Information kann auch per Ajax-XMLHttpRequest geholt werden, sofern alles von derselben Domain kommt:
PHP:
function callback(rText) {
	var j = eval("(" + rText + ")");
	var ip=j.serverinfo[0].ip;
	alert("Deine IP ist " + ip);
}
var myxhr = new xhpj();
myxhr.GetTxt("http://localhost/ajax/serverinfojsonp.php",callback);
Das verwendete vielseitige xhpj-object wurde hier inclusive Code vorgestellt.
 
Zuletzt bearbeitet:
Gut beschrieben... aber natürlich find' ich was zum meckern ;)

Diese Zeile:
Code:
$ip =($_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER["REMOTE_ADDR"];
kann eine Notiz erzeugen:
Notice: Undefined index: HTTP_X_FORWARDED_FOR
Besser vorher alle Indizes im Array mit array_key_exists überprüfen... man kann sich einfach auf nichts verlassen, was vom Browser kommt - und dass es auch kommt.
 
Der Hinweis ist richtig, jedoch liefern die Server mit denen ich bisher gearbeitet habe per Standard keine E_NOTICE, sondern nur Warnungen und Fehler.
Die Zeile ist aus einer Applikation, die schon einige Jahre ohne Probleme läuft. Hab im Code zur Sicherheit 'error_reporting(E_ALL ^ E_NOTICE);' zugefügt. Um die Notice zu sehen ist in den meisten Fällen ein Aufruf von error_reporting(E_ALL); notwendig.
Das Beispiel ist sowieso etwas an den Haaren herbeigezogen, denn für solche Informationen brauche ich keinen JSON Webservice. Ich wollte das Beispiel jedoch einfach halten.
 
Zurück
Oben