Mike: xmlHttpRequest nicht auf gleiche Seite verweisen?

Hallo,

noch mal eine Frage zum xmlHttpRequest()

Bei meinem letzten Beispiel habe ich versucht die Ausgabeseite (test.php) mit der Aufrufseite zu kombinieren:

  
<?php  
  
if($_GET['q'])  
{  
// echo $_GET['q'];  
echo 'egal....';  
die();  
}  
?><html>  
<head>  
<script type="text/javascript">  
function starteAjax(url) {  
var req = new XMLHttpRequest();  
....

Also ich rufe die Seite auf, der xmlHttpRequest ruft die gleiche seite aus, bekommt aber nur den von PHP generiereten Output. Mir fiel auch zuerst gar nicht auf, dass das nicht funktionierte, weil ich die URL einen Parameter übergab, den PHP dann darstellen sollte also test.php?q=abc liefert natürlich dann auch "abc". Als ich dann, wie im Code einen anderen Wert ausgeben wollte(egal....) kam trotzdem "abc".

Wenn aber die Ausgabedatei  != die Aufrufdatei ist, also seperate Seite dann klappt alles.

Daher 2 Fragen:

Ist das Verhalten so vorgesehen und richtig, kann ich also nicht alles in einer Datei kombinieren?

Wieso nimmt der Request dann den URL-Parameter (q=abc) als angebliche xmlHttpRequest-Ausgabe an?

  1. Moin,

    Bei meinem letzten Beispiel habe ich versucht die Ausgabeseite (test.php) mit der Aufrufseite zu kombinieren:

    <?php
    if($_GET['q'])
    {
    // echo $_GET['q'];
    echo 'egal....';
    die();
    }
    ?><html>
    <head>
    <script type="text/javascript">
    function starteAjax(url) {
    var req = new XMLHttpRequest();
    ....

    
    > Also ich rufe die Seite auf, der xmlHttpRequest ruft die gleiche seite aus, bekommt aber nur den von PHP generiereten Output.  
      
    Sobald das Skript einen Parameter q übergeben bekommt, gibt es "egal..." aus und stirbt ([man beachte das hier](http://community.de.selfhtml.org/zitatesammlung/zitat1282)).  
      
    
    > Mir fiel auch zuerst gar nicht auf, dass das nicht funktionierte, weil ich die URL einen Parameter übergab, den PHP dann darstellen sollte also test.php?q=abc liefert natürlich dann auch "abc". Als ich dann, wie im Code einen anderen Wert ausgeben wollte(egal....) kam trotzdem "abc".  
      
    Sicher, dass du das Skript korrekt abgespeichert hast, und der Server auch dieses Skript ausführt?  
      
    
    > Wenn aber die Ausgabedatei  != die Aufrufdatei ist, also seperate Seite dann klappt alles.  
      
    Ich denke hier liegt ein Fehler in der URL und/oder dem Skript vor.  
      
    
    > Ist das Verhalten so vorgesehen und richtig, kann ich also nicht alles in einer Datei kombinieren?  
      
    Doch, grundsätzlich ist es möglich innerhalb eines Skripts sowohl Javascript-Code auszuliefern, als auch per AJAX dasselbe Skript parametriert aufzurufen um eine Information zu bekommen.  
      
    
    > Wieso nimmt der Request dann den URL-Parameter (q=abc) als angebliche xmlHttpRequest-Ausgabe an?  
      
    Wie gesagt: Ich meine, dass die URL, die du für den AJAX-Request benutzt auf ein (veraltetes) Skript zeigt, in dem noch die mittlerweile auskommentierte Zeile aktiv ist. Du benutzt IMHO entweder eine falsche URL oder das Skript ist nicht in der neuesten Version im korrekten Verzeichnis.  
      
    Grüße Marco
    
    -- 
    Ich spreche Spaghetticode - fließend.
    
    1. Hallo,

      Sobald das Skript einen Parameter q übergeben bekommt, gibt es "egal..." aus und stirbt (man beachte das hier).

      schon klar, für Testzwecke sollte es aber OK sein.

      Sicher, dass du das Skript korrekt abgespeichert hast, und der Server auch dieses Skript ausführt?

      100% sicher.

      Wie gesagt: Ich meine, dass die URL, die du für den AJAX-Request benutzt auf ein (veraltetes) Skript zeigt, in dem noch die mittlerweile auskommentierte Zeile aktiv ist. Du benutzt IMHO entweder eine falsche URL oder das Skript ist nicht in der neuesten Version im korrekten Verzeichnis.

      Nein so wird's nicht sein, denn es funktioniert ja ansonsten. Nochmal das komplette Script zum testen.

      Seite: selftest.php

        
        
      <?php  
      if($_GET['q']){echo 'intern';die();}  
      ?><html>  
      <head>  
      <title>selftest</title>  
      <meta http-equiv="content-type" content="text/html; charset=utf-8">  
      <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">  
      <meta http-equiv="expires" content="0">  
        
        
      <script type="text/javascript">  
        
      function starteAjax(url) {  
        
        
      var req = new XMLHttpRequest();  
        
      req.open( "GET", url, true );  
      req.setRequestHeader("Pragma", "no-cache");  
      req.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate");  
      req.onreadystatechange = meineCallbackFkt;  
      req.send( null );  
        
      }  
        
      function meineCallbackFkt() {  
        
      if( 4 == this.readyState )  
      {  
        if( 200 != this.status ) {alert( "Fehler " + this.status + ": " + this.statusText );  
        }else  
            {  
            // ergebnis verarbeiten  
            // alert( req.responseText );  
            document.getElementById('output').innerHTML += '<h3>'+this.responseText+'</h3>';  
        
            }  
        
        
        }  
      }  
      </script>  
        
      </head>  
      <body>  
        
      <h2>Test</h2>  
        
        
      <button onclick="starteAjax('selftest.php?q=x');starteAjax('test.php?q=x');">Starte Ajax mit dieser Datei</button>  
      <button onclick="starteAjax('out.php?q=x');starteAjax('out.php?q=x');">Starte Ajax mit externer Datei</button>  
      <p id="output"></p>  
      </body>  
      </html>  
        
      
      

      Die externe Seite: out.php

        
      <?php  
      if($_GET['q']){echo 'extern';die();}  
      ?><  
      
      

      Wenn ich den button intern aufrufe bekomme ich als Ausgabe: "intern" und "x"

      Wenn ich den button extern aufrufe bekomme ich die richtige Ausgabe: "extern" und "extern"

      Habe schon an Cachepropleme gedacht und daher noch die headerangaben hinzugefügt, browsercache gelöscht, alles mögliche...

      Sehr seltsam das Ganze...

      1. Sicher, dass du das Skript korrekt abgespeichert hast, und der Server auch dieses Skript ausführt?

        100% sicher.

        ups, Du hast recht, von wegen 100% sicher ;-)

        dank dir.

    2. Sobald das Skript einen Parameter q übergeben bekommt, gibt es "egal..." aus und stirbt (man beachte das hier).

      Er hätte mit die('whatever'); auch gleich die Ausgabe machen können. Da es sich hier um Tests/Debugging handelte würde ich nicht meckern. "Stirb" klinkt halt mehr nach Prosa als dieses vergleichbar hässliche Wort "exit".

      Das eigentliche Problem:

      wenn die Seite mit http://example.com/test.php?q=foobar aufgerufen wurde, dann könnte es gut sein, dass die Rückgabe sorgfältig im Cache aufbewahrt wird. Wenn jetzt also ein xmlHttpRequest wieder http://example.com/test.php?q=foobar aufruft, dann kommt das vermeintlich falsche Ergebnis wahrscheinlich aus dem Cache.

      Das kann man sich anschauen, wenn man den Datenverkehr mit geeigneten Entwicklertools beobachtet.
      Will man das vermeiden, so hänge man an http://example.com/test.php?q=foobar noch eine mit JS generierte, große Zufallszahl ran um den Request an den Server zu erzwingen.

      http://example.com/test.php?q=foobar&z=ZUFALLSZAHL

      Jörg Reinholz

      1. Das kann man sich anschauen, wenn man den Datenverkehr mit geeigneten Entwicklertools beobachtet.
        Will man das vermeiden, so hänge man an http://example.com/test.php?q=foobar noch eine mit JS generierte, große Zufallszahl ran um den Request an den Server zu erzwingen.

        http://example.com/test.php?q=foobar&z=ZUFALLSZAHL

        Variante 2 (zu bevorzugen)

        Sende mittels des PHP-Skriptes HTTP-Header aus, welche das Cachen verbieten:

        header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); # Datum in der Vergangenheit  
        header( 'Cache-Control: no-store, no-cache, must-revalidate' );  
        header( 'Pragma: no-cache' );  
        
        

        sollte reichen. Zu bevorzugen ist das, weil der Aufwand an der Stelle erfolgt, wo Du mehr Kontrolle hast, bzw. wo die Daten erzeugt werden. Außerdem macht es Sinn, gleich das Cachen zu unterbinden und nicht den dann sinnlos gespeicherten Cache zu umgehen.

        Jörg Reinholz

      2. Moin,

        wenn die Seite mit http://example.com/test.php?q=foobar aufgerufen wurde, dann könnte es gut sein, dass die Rückgabe sorgfältig im Cache aufbewahrt wird.

        Das wäre eine Möglichkeit, allerdings cachen meines Wissens die aktuellen Browser per default keine Responses von PHP-Skripten. Kann ich allerdings nur durch einige Tests vermuten, ich habe dazu jetzt keine Quelle gefunden (mit aktuellen Chrome und FF probiert).

        Grüße Marco

        --
        Ich spreche Spaghetticode - fließend.
        1. Das wäre eine Möglichkeit, allerdings cachen meines Wissens die aktuellen Browser per default keine Responses von PHP-Skripten.

          Äh. Da stellt sich die Frage, wie die Browser das denn mitbekommen sollen. Jetzt komm mir aber nicht mit ".php".

          Jörg Reinholz

          1. Moin,

            Äh. Da stellt sich die Frage, wie die Browser das denn mitbekommen sollen. Jetzt komm mir aber nicht mit ".php".

            Keine Ahnung. Fakt ist, dass ich mit Chrome und FF und verschiedenen Servern in der Default-Einstellung nichts gecached wurde. Kleine Änderungen am entsprechenden Skript (von einem anderen Computer aus) wurden immer direkt wirksam. Oder ist das bei dir anders?

            Grüße Marco

            --
            Ich spreche Spaghetticode - fließend.
            1. Hallo,

              Äh. Da stellt sich die Frage, wie die Browser das denn mitbekommen sollen. Jetzt komm mir aber nicht mit ".php".
              Keine Ahnung. Fakt ist, dass ich mit Chrome und FF und verschiedenen Servern in der Default-Einstellung nichts gecached wurde.

              das liegt dann aber nicht an PHP an sich, sondern daran, dass Apache typischerweise von sich aus fürs Caching geeignete Header mitsendet (z.B. Modified, ETag), wenn er statische Ressourcen ausliefert, während er das bei dynamisch generierten Ressourcen nicht tut. Das darf das Script aber gern selbst tun, dann wird auch PHP-generierter Inhalt gecacht.

              Ciao,
               Martin

              --
              Wenn man sieht, was der liebe Gott auf der Erde so alles zulässt, hat man das Gefühl, er experimentiert immer noch.
                (Sir Peter Ustinov, Charakterdarsteller, †2004)
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              1. das liegt dann aber nicht an PHP an sich, sondern daran, dass Apache typischerweise von sich aus fürs Caching geeignete Header mitsendet (z.B. Modified, ETag), wenn er statische Ressourcen ausliefert, während er das bei dynamisch generierten Ressourcen nicht tut.

                Jein. Ich weiß jetzt nicht, was die Default-Konfiguration ist. Ich habe aber in den Antwortheadern bei dynamischen Ressourcen schon oft den Abrufzeitpunkt als Datum der letzten Änderung gesehen. Das macht nur beschränkt Sinn - denn viele "dynamische Ressourcen" (also PHP-Skripte)  liefern tatsächlich statische Inhalte aus. Gerade bei Content-Management-Systemen wird eine Unmenge an Last sinnlos "verbraten".

                ETag ist dann wieder eine Geschichte, die bei must-revalidate wirksam wird und benutzt wird, wenn die Steuerung des Cachings über den Last-Modified-Wert oder expires zu kompliziert erscheint.

                Das darf das Script aber gern selbst tun, dann wird auch PHP-generierter Inhalt gecacht.

                Die header selbst zu setzen ist goldrichtig, das wird von vielen aber nicht bedacht.

                Jörg Reinholz

            2. Keine Ahnung. Fakt ist, dass ich mit Chrome und FF und verschiedenen Servern in der Default-Einstellung nichts gecached wurde. Kleine Änderungen am entsprechenden Skript (von einem anderen Computer aus) wurden immer direkt wirksam. Oder ist das bei dir anders?

              Merksatz: Viele Browser missachten beim Drücken von [F5] sinnvollerweise den eigenen Cache und laden vom Server neu. Das ist was ganz anderes.

              Ich setze mal voraus, dass der Server Header setzt, die das Cachen ermöglichen. Dann sieht das so aus:

              A)
              relevante Seite aufrufen -> Quelle ändern -> andere Seite aufrufen -> relevante Seite über Link oder Änderung der URL aufrufen = altes Ergebnis

              B)
              relevante Seite aufrufen -> Quelle ändern -> [F5] = neues Ergebnis

              Wenn man jetzt PHP-Seiten entwickelt, dann drückt man immer mal [F5] und kommt natürlich, wenn man obigen Merksatz nicht kennt, zum falschen Eindruck.

              Das hat mit PHP insgesamt weniger zu tun. Meine Seiten auf fastix.org werden mit PHP erzeugt und sowohl serverseitig also auch im Browser im Cache gespeichert...

              Jörg Reinholz

              1. Hallo,

                Merksatz: Viele Browser missachten beim Drücken von [F5] sinnvollerweise den eigenen Cache und laden vom Server neu. Das ist was ganz anderes.

                da ist meine Erfahrung der letzten Jahre mit Opera und davor viele Jahre mit IE genau umgekehrt: Ein einfaches Reload oder auch das Betätigen des Back-Buttons holt meist nur den Cache-Inhalt hervor, beim Klicken auf einen Link wird die Ressource neu angefordert.

                A)
                relevante Seite aufrufen -> Quelle ändern -> andere Seite aufrufen -> relevante Seite über Link oder Änderung der URL aufrufen = altes Ergebnis

                B)
                relevante Seite aufrufen -> Quelle ändern -> [F5] = neues Ergebnis

                Mag sein, dass Firefox und/oder Chrome so ticken, die kenne ich nicht so gut; IE bis einschließlich 8 sowie Opera bis 12 jedenfalls genau andersrum. Mit Ctrl-F5 (oder war's Shift-F5?) kann ich aber ein Neuladen erzwingen.

                Ciao,
                 Martin

                --
                Funktion und Referenz auf diese sind mir bekannt, mit Zeigern kann ich nicht viel mehr anfangen, als damit auf Buttons zu klicken.
                  (Ashura)
                Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              2. Moin,

                Merksatz: Viele Browser missachten beim Drücken von [F5] sinnvollerweise den eigenen Cache und laden vom Server neu. Das ist was ganz anderes.

                Nein, das ist offensichtlich nicht so, denn für einen Reload der den Cache ignoriert gibt es einen eigenen Shortcut sowohl für FF als auch für Chrome (Shift + F5). Das bedeutet im Umkehrschluss: F5 ignoriert den Cache nicht.

                Grüße Marco

                --
                Ich spreche Spaghetticode - fließend.
                1. Nein, das ist offensichtlich nicht so, denn für einen Reload der den Cache ignoriert gibt es einen eigenen Shortcut sowohl für FF als auch für Chrome (Shift + F5). Das bedeutet im Umkehrschluss: F5 ignoriert den Cache nicht.

                  Shift + F5 öffnet in meinem Firefox die Webkonsole. Und ich habe da nicht dran rumgespielt.

                  Auch bitte ich sehr ernsthaft darum, meine Äußerungen genau zu lesen. Ich schrieb:

                  Viele Browser missachten beim Drücken von [F5] sinnvollerweise den eigenen Cache

                  "Viele Browser" heißt nicht "alle Browser", es bedeutet sogar "nicht alle Browser".

                  Jörg Reinholz

                  1. Moin,

                    Shift + F5 öffnet in meinem Firefox die Webkonsole. Und ich habe da nicht dran rumgespielt.

                    Bei FF ist es meines Wissens STRG+F5.

                    Auch bitte ich sehr ernsthaft darum, meine Äußerungen genau zu lesen. Ich schrieb:

                    Ich weiß, was du geschrieben hast. IE, FF und Chrome sind jedoch die am meisten genutzten Browser.

                    Grüße Marco

                    --
                    Ich spreche Spaghetticode - fließend.
            3. Hallo,

              Äh. Da stellt sich die Frage, wie die Browser das denn mitbekommen sollen. Jetzt komm mir aber nicht mit ".php".

              Keine Ahnung. Fakt ist, dass ich mit Chrome und FF und verschiedenen Servern in der Default-Einstellung nichts gecached wurde. Kleine Änderungen am entsprechenden Skript (von einem anderen Computer aus) wurden immer direkt wirksam. Oder ist das bei dir anders?

              Nur der Vollständigkeit halber und weil ich das Problemn auch schon hatte: Der IE neigt dazu, den AJAX-Request mit Standardeinstellungen aus dem Cache zu holen. Ich weiß aber nicht, ob das mit IE10 erledigt ist.

              Viele Grüße
              Siri

        2. Hallo,

          Das wäre eine Möglichkeit, allerdings cachen meines Wissens die aktuellen Browser per default keine Responses von PHP-Skripten. Kann ich allerdings nur durch einige Tests vermuten, ich habe dazu jetzt keine Quelle gefunden (mit aktuellen Chrome und FF probiert).

          Doch tun sie (IE10), insbesondere eben bei meinen Tests. Abhilfe schaffte aber:

          req.setRequestHeader("Pragma", "no-cache");
          req.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate");