Mike: xmlHttpRequest als xml nur mit Dateiendung .xml?

Hallo,

wieder mal eine Frage zu Ajax. Ich habe überlegt ob ich diese Frage eine andere von mir anhänge, denke aber separat, da anderer doch etwas anderer Frageninhalt. Oder soll ich ähnliche Fragen eher zusammenfassen?

Es geht diesmal im Gegensatz zu Text um XML lesen und verarbeiten. Dazu habe ich ein Script gefunden und wollte den XML-Output durch PHP generieren lassen. Geht aber nicht.

Auch ein Versuch die Ausgabe statisch als XML.html zu nutzen bringt kein Erfolg. Einzig wenn ich die Ausgabe als Datei mit der Endung .xml nutze, funktioniert alles wie gewünscht.

Ich habe 2 alerts() eingebaut um zu sehen was wirklch ankommt. responseText kommt ohne Probleme rein nur eben kein responseXML.  Nach allem was ich gelesen habe müsste es doch gehen, allenfalls ein MIME-Type Problem, doch dafür habe ich auch nochmal extra die Header im php gesetzt ohne Erfolg.

Woran liegts?

Testseite.html
  
<html>  
<head>  
<title>Verarbeitung von XML-Dateien mit Ajax</title>  
<meta charset="utf-8">  
  
<script type="text/javascript">  
  
var xmldata = null;  
    xmldata = new XMLHttpRequest();  
  
function xmlData() {  
  
    if (xmldata.readyState == 4) {  
  
alert("Als XML kommt gar nichts\r\n"+xmldata.responseXML);  
  
alert("Als Text ohne Probleme\r\n"+xmldata.responseText);  
  
        var inhalt = xmldata.responseXML;  
        var ifluss = inhalt.getElementsByTagName("Fluss").length;  
        var antwt1 = inhalt.getElementsByTagName("titel")[0].firstChild.nodeValue;  
  
        document.getElementById("ausg-01").innerHTML = antwt1;  
  
        for (var i = 0; i < ifluss; i++){  
  
            var antwt2 = inhalt.getElementsByTagName("Fluss")[i].getAttribute("Name");  
            var antwt3 = inhalt.getElementsByTagName("Fluss")[i].getAttribute("Laenge");  
  
            document.getElementById("ausg-02").innerHTML += "<li>" + antwt2 + " - " + antwt3 + "</li>";  
        }  
    }  
}  
  
window.onload = function() {  
  
    xmldata.open("GET", "xml.html", true);  
  
// xml.html, xml.php, einzig test.xml geht  
  
  
    xmldata.onreadystatechange = xmlData;  
    xmldata.send(null);  
}  
  
</script>  
</head>  
  
<body>  
<div class="ausg">  
<h1>Verarbeitung von XML-Dateien</h1>  
<h2 id="ausg-01"></h2>  
<ul id="ausg-02"></ul>  
</div>  
</body>  
</html>  

XML.php ###  // funktioniert nicht
  
<?php  
  
 header('Content-Type: text/xml');  
 header ('Cache-Control: no-cache');  
  
echo '<?xml version="1.0" encoding="utf-8" ?>  
  <Response>  
    <Antwort>  
      <titel>Die längsten Flüsse</titel>  
      <Fluesse>  
        <Fluss Name="Nil" Laenge="6.852"/>  
        <Fluss Name="Amazonas" Laenge="6.448"/>  
        <Fluss Name="Jangtsekiang" Laenge="6.380"/>  
        <Fluss Name="Mississippi" Laenge="3.778"/>  
        <Fluss Name="Jenissei" Laenge="5.540"/>  
        <Fluss Name="Ob" Laenge="3.650"/>  
        <Fluss Name="Amur" Laenge="2.824"/>  
      </Fluesse>  
    </Antwort>  
  </Response>  
  ';  
  
die();  
  
  
?>  

test.xml ### // Funktioniert
  
<?xml version="1.0" encoding="utf-8" ?>  
  <Response>  
    <Antwort>  
      <titel>Die längsten Flüsse</titel>  
      <Fluesse>  
        <Fluss Name="Nil" Laenge="6.852"/>  
        <Fluss Name="Amazonas" Laenge="6.448"/>  
        <Fluss Name="Jangtsekiang" Laenge="6.380"/>  
        <Fluss Name="Mississippi" Laenge="3.778"/>  
        <Fluss Name="Jenissei" Laenge="5.540"/>  
        <Fluss Name="Ob" Laenge="3.650"/>  
        <Fluss Name="Amur" Laenge="2.824"/>  
      </Fluesse>  
    </Antwort>  
  </Response>  

xml.html ### // Funktioniert nicht
  
<?xml version="1.0" encoding="utf-8" ?>  
  <Response>  
    <Antwort>  
      <titel>Die längsten Flüsse</titel>  
      <Fluesse>  
        <Fluss Name="Nil" Laenge="6.852"/>  
        <Fluss Name="Amazonas" Laenge="6.448"/>  
        <Fluss Name="Jangtsekiang" Laenge="6.380"/>  
        <Fluss Name="Mississippi" Laenge="3.778"/>  
        <Fluss Name="Jenissei" Laenge="5.540"/>  
        <Fluss Name="Ob" Laenge="3.650"/>  
        <Fluss Name="Amur" Laenge="2.824"/>  
      </Fluesse>  
    </Antwort>  
  </Response>  

  1. Es geht diesmal im Gegensatz zu Text um XML lesen und verarbeiten. Dazu habe ich ein Script gefunden und wollte den XML-Output durch PHP generieren lassen. Geht aber nicht.

    Auch ein Versuch die Ausgabe statisch als XML.html zu nutzen bringt kein Erfolg. Einzig wenn ich die Ausgabe als Datei mit der Endung .xml nutze, funktioniert alles wie gewünscht.

    Jede HTTP-Antwort wird mit einer Content-Type-Angabe versehen, die über die Art der gesendeten Daten Auskunft gibt. Bei normalen Dateien entscheidet der Webserver üblicherweise anhand der Dateiendung, welche Content-Type-Angabe gesendet wird.

    Wenn du deine Datei XML.html benennst, taucht der Endung .html entsprechend "Content-Type: text/html" im Antwortkopf auf. Daran hält sich der Browser (wenn's kein IE ist) und du kannst nicht erwarten, dass er Daten, die du als HTML kennzeichnen lässt, als XML verarbeitet.

    PHP gibt automatisch text/html aus, sofern nichts anderes im Skript definiert wird.

    Es kann also von Haus aus weder mit XML.html, noch mit XML.php etwas in .responseXML auftauchen, nur mit XML.xml.

    Nach allem was ich gelesen habe müsste es doch gehen, allenfalls ein MIME-Type-Problem,

    Sehe ich auch so.

    doch dafür habe ich auch nochmal extra die Header im php gesetzt, ohne Erfolg.

    Den musst du nicht "nochmal extra" setzen, den _musst_ du setzen, siehe oben.

    <?php

    header('Content-Type: text/xml');
    header ('Cache-Control: no-cache');

    echo '<?xml version="1.0" encoding="utf-8" ?>
      <Response>

    </Response>
      ';

    die();

    ?>

    Jetzt mal abgesehen davon, dass die() am Ende des Skriptes restlos überflüssig ist, ist es soweit in Ordnung und sollte machen, was du wünscht.

    Besorge dir Firefox und dazu die Firefox-Erweiterung Firebug. Firebug hat eine Netzwerkseite, auf der du jede Anfrage und die Antwort dazu genau nachverfolgen kannst. Prüfe damit, ob dein Skript wirklich das sendet, was es senden soll, namentlich die Content-Type-Angabe text/xml. PHP und seine oftmals etwas unbedarften Anwender sind da etwas problematisch.

    Alternativ kannst du auch einfach das Skript selbst im Browser aufrufen. Eigentlich müsste er es dann in der ein oder anderen Form als XML-Daten ausgeben bzw. darauf hinweisen. Das hängt aber vermutlich vom Browser ab, insofern empfehle ich dir dringend, lieber mit Firebug genau hinzugucken, als zu interpretieren, was der Browser sich vielleicht oder vielleicht auch nicht bei diesem oder jenem gedacht haben mag.

    1. Hallo,

      <?php

      header('Content-Type: text/xml');
      header ('Cache-Control: no-cache');

      echo '<?xml version="1.0" encoding="utf-8" ?>
        <Response>

      </Response>
        ';

      die();

      ?>

      Jetzt mal abgesehen davon, dass die() am Ende des Skriptes restlos überflüssig ist, ist es soweit in Ordnung und sollte machen, was du wünscht.

      Nein macht es eben nicht, es wird immer(IE10) als text/html ausgeliefert. Habe nun aber doch etwas gefunden womit es geht. Wichtiger als die Headerangabe im PHP-File scheint die Anfrage zu sein, denn der folgende Zusatz bringt den Erfolg, selbst wenn ich die Header im PHP weglasse:

      xmldata.setRequestHeader("Content-Type", "Text/xml");

      1. Hallo,

        Wichtiger als die Headerangabe im PHP-File scheint die Anfrage zu sein, denn der folgende Zusatz bringt den Erfolg, selbst wenn ich die Header im PHP weglasse:

        xmldata.setRequestHeader("Content-Type", "Text/xml");

        Du scheinst Anfrage- mit Antwort-Headern zu verwechseln.

        Content-Type ist ein Antwort-Header*, den der Server schickt. Er ist kein Anfrage-Header*, daher ist setRequestHeader("Content-Type", "…") auf dem Client im Grunde Unsinn.

        Da es sich um einen Antwort-Header handelt, ist es schon richtig, dass das PHP-Script *serverseitig* selbigen Header setzt. Genau das tut eben: header('Content-Type: text/xml');

        Dass der setRequestHeader-Aufruf in deinem Fall etwas ändert, kann ich mir nicht erklären. Wenn der Server den Content-Type text/xml – oder besser application/xml – sendet, dann sollte der Browser versuchen, die Antwort als XML zu parsen. Wenn es sich um ein wohlgeformtes XML-Dokument handelt, ist der DOM-Zugriff über responseXML möglich.

        (* bei GET-Anfragen. Bei POST und PUT ist er als Anfrage-Header möglich, um den Inhaltstyp der Daten im Anfrage-Body anzugeben.)

        Grüße,
        Mathias

        1. Dass der setRequestHeader-Aufruf in deinem Fall etwas ändert, kann ich mir nicht erklären.

          Ich würde als MÖGLICHE Erklärung mal wieder in Betracht ziehen, dass im Browsercache irgend was fehlerhaftes liegt. Mit dem geänderten RequestHeader wird der Browser wohl auch den Cache ignorieren - weil der ja mit anderen Voraussetzungen erfolgte.

          Jörg Reinholz

  2. Ich kann das Verhalten nicht nachvollziehen.

    Sowohl

    alert("Als response:\r\n"+JSON.stringify(xmldata.response));

    liefert erwartungsgemäß:

    "<?xml version="1.0" encoding="utf-8" ?>\n  <Response>\n    <Antwort>\n      <titel>Die längsten Flüsse</titel>\n      <Fluesse>\n        <Fluss Name="Nil" Laenge="6.852"/>\n        <Fluss Name="Amazonas" Laenge="6.448"/>\n        <Fluss Name="Jangtsekiang" Laenge="6.380"/>\n        <Fluss Name="Mississippi" Laenge="3.778"/>\n        <Fluss Name="Jenissei" Laenge="5.540"/>\n        <Fluss Name="Ob" Laenge="3.650"/>\n        <Fluss Name="Amur" Laenge="2.824"/>\n      </Fluesse>\n    </Antwort>\n  </Response>"

    alert("Als XML:\r\n"+xmldata.responseXML);

    liefert als XML nicht etwa nichts, sondern erwartungsgemäß:

    [object XMLDocument]

    Du verarbeitest ja auch das XML-Objekt weiter:

    var inhalt = xmldata.responseXML;

    ... und das funktioniert schließlich auch. Ich bekomme im Firefox und Chromium jedenfalls das erwartete Ergebnis.

    Und zwar sowohl sowohl mit der PHP-Datei als auch mit der XML-Datei. Der "Fehler" liegt also an anderer Stelle.

    Jörg Reinholz