• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[js]Textdatei zyklisch mit Ajax einlesen

jspit

Lounge-Member
In einer Textdatei liegen Informationen, die per FTP laufend aktualisiert werden. Diese Informationen möchte ich zyklisch per Ajax einlesen um bestimmte Objekte der Seite aktualisieren. Das Ganze soll so gestaltet werden, daß seitenspezifische Aktionen und alles was xhr/timer betrifft so wenig wie möglich vermischt werden.
Da ich noch nicht viel mit Ajax gearbeitet habe, möchte ich bevor ich mich verenne meinen Ansatz hier vorstellen:

PHP:
<html>
<head>
<title>Ajax Test 3</title>
<script type="text/javascript">

function xhpj() {
  var xho = window.XMLHttpRequest? new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); //IE ab 5.5
  var csurl, cfkt, czyksek, to;
  var rfkt = function(){
    if (xho) {
      xho.open('post', csurl , true);
      xho.onreadystatechange = function () {
        if (xho.readyState == 4) cfkt(xho.responseText);
        }
      xho.send(null);
      if(czyksek) to=window.setTimeout(rfkt,czyksek * 1000);
    };
  }
  this.GetTxt = function (surl,fkt,zyksek) {
    csurl = surl;
    cfkt = fkt;
    czyksek = zyksek;
    if (xho) rfkt();
  }
  this.ClearZyk = function (){window.clearTimeout(to);}
}

//seitenspezifische function
function myfkt(rText){
document.getElementById("testdiv").innerHTML = rText;
}

//Objectinstanz erzeugen
var myxmlhttp = new xhpj();
//test.txt wird alle 2 Sekunden eingelesen und dann myfkt aufgerufen 
myxmlhttp.GetTxt("test.txt",myfkt,2);

</script>
</head><body>
<div id="testdiv">test</div>
<button onclick="myxmlhttp.ClearZyk()">Stop</button>
</body></html>

Kommentare zum Code:

- Auf Uraltbrowser < IE 5.5 wurde verzichtet. Dadurch entfällt das übliche try case für die ActiveX-Varianten.
- Es existiert eine function myfkt für die seitenspezifischen Aktionen welche einmalig/zyklisch aufgrufen wird.
- Aktiviert wird das Ganze durch GetTxt mit den Parametern Dateiname, Funktionsname und Aktualisierungsintervall. Fehlt das Intervall oder ist es 0 wird der Request nur eimalig ausgeführt.
- Das ist auch für ein Einlesen von js geeignet, myfkt muss dafür minimal erweitert werden.
- Es wurde minimaler Codeumfang angestrebt mit Blickrichtung auf Embedded-Webserver

Das Ganze scheint erstmal so zu funktionieren. Nun meine Fragen/Problemchen:
- ist so etwas notwendig um ein eventuelles Cacheproblem zu umgehen?
xho.open('post', csurl + "?r=" + Math.round(Math.random()*1000), true);
- Gibt es eine Alternative für die Zuweisungen csurl = surl; usw.

Bin auch dankbar für Tipps + Kommentare.
 
Zuletzt bearbeitet:
du kannst dir die callbacks/parameter des xhr überschreiben, wenn deine antwort vom server noch nicht da ist im zyklischen betrieb
Stimmt, danke. Muss ich nochmal überdenken.

Cache-Problem: Hatte den Eindruck geht auch ohne. Werd es einbauen.

wie meinst du das?

Ich hab versucht aus der function rfkt irgendwie auf die parameter surl,fkt,zyksek von GetTxt zuzugreifen. Diese Sicht scheint es aber nicht zu geben.
 
Ich hab versucht aus der function rfkt irgendwie auf die parameter surl,fkt,zyksek von GetTxt zuzugreifen. Diese Sicht scheint es aber nicht zu geben.
nein, du könntest es deinem xhpj-obj. aber im konstruktor mitgeben
ach so, du könntest rfkt auch in GetTxt legen
 
Zuletzt bearbeitet:
Nur der IE hat, soweit ich weiß, das Cache Problem, das läßt sich aber auch beheben wenn der header explizit sagt, dass die Seite nicht gechached wird (unter Vorbehalt, ich hab das gelesen und noch nicht selber ausprobiert)
 
du könntest rfkt auch in GetTxt legen

Super Tipp, die function sieht jetzt so aus, ist nur auf die schnelle getestet:
PHP:
function xhpj() {
  var xho = window.XMLHttpRequest? new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); //IE ab 5.5
  var to;
  this.GetTxt = function (surl,fkt,zyksek) {
    var rfkt = function(){
      if (xho) {
        xho.open('post', surl + "?r=" + Math.round(Math.random()*1000), true);
        xho.onreadystatechange = function () {
          if (xho.readyState == 4) {
            if(xho.status == 200) fkt(xho.responseText);
            if(zyksek) to=window.setTimeout(rfkt,zyksek * 1000);
          }
        }
        xho.send(null);
      }
    }
    if(xho) rfkt();
  }
  this.ClearZyk = function (){window.clearTimeout(to);}
}

@ein schlauer
Mit "der header" ist der von meiner txt-Datei gemeint? Da hab ich kein Einfluss drauf.
 
Der IE cached die Antwort nur bei GET - nicht bei POST... steht wenigstens so bei MSDN.
Internet Explorer caches the results of HTTP GET requests in the Temporary Internet Files (TIF) folder. In most cases, caching improves performance for data that will not change frequently. To guarantee that the results are not cached, use POST.
 
Vielen Dank für die Tipps und Hinweise. Tests mit der letzten Variante des xhpj-objectes liefen zufriedenstellend. Das xhpj-object ist jetzt so richtig nach meinem Geschmack, da vielseitig nutzbar ohne im xhpj-object ändern zu müssen. Im Netz wird immer wieder von Cache-Problemen auch bei post berichtet, deshalb hab ich den Zufallsparameter zur Sicherheit im open belassen. Hier ein Komplettbeispiel für ein dynamisches include von html:
include1.html
PHP:
<h1>Eine Überschrift</h1>
<p>Ein Absatz</p>

Komplettbeispiel:
PHP:
<html>
<head>
<title>Ajax Test include html</title>
<script type="text/javascript">
function xhpj() {
  var xho = window.XMLHttpRequest? new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); //IE ab 5.5
  var to;
  this.GetTxt = function (surl,fkt,zyksek) {
    var rfkt = function(){
      if (xho) {
        xho.open('post', surl + "?r=" + Math.round(Math.random()*1000), true);
        xho.onreadystatechange = function () {
          if (xho.readyState == 4) {
            if(xho.status == 200) fkt(xho.responseText);
            if(zyksek) to=window.setTimeout(rfkt,zyksek * 1000);
          }
        }
        xho.send(null);
      }
    }
    if(xho) rfkt();
  }
  this.ClearZyk = function (){window.clearTimeout(to);}
}
var myxhr = new xhpj();
</script>
</head><body>
<div>vorhandenes div</div>

<div id="testdiv">test</div>
<script type="text/javascript">
myxhr.GetTxt("include1.html",function (rText){document.getElementById("testdiv").innerHTML = rText ;});
</script>

<div>vorhandenes div</div>
</body></html>

Das Nachladen von Javascript kann auch per Ajax mit dem xhpj-object erfolgen. Die js-Datei muss jedoch von der selben Domain kommen.

include3.js
PHP:
var my=125;
var my2="my2";

Dafür muss nur myfkt geringfügig modifiziert werden, um die Variablen aus include3.js nutzen zu können.
PHP:
<div id="testdiv">test</div>
<script type="text/javascript">
function myfkt(rText){
  eval(rText);
  document.getElementById("testdiv").innerHTML = my2 + " " + my ;
  }
myxhr.GetTxt("include3.js",myfkt);
</script>


Da alle guten Dinge 3 sind, noch ein Beispiel zur Anzeige von html Quellcode mit Ajax:
PHP:
<div id="testdiv">test</div>
<script type="text/javascript">
function myfkt(rText){
var src = rText.replace(/</g,"<").replace(/>/g,">");
document.getElementById("testdiv").innerHTML = "<pre>" + src + "<\/pre>" ;
}
myxmlhttp.GetTxt("ajaxtest5.html",myfkt);
</script>

Gruß
jspit
 
Hallo.
erstmal Entschuldigung, dass ich den alten Thread wieder ausgrabe als meine erste Handlung hier, aber thematisch habe ich ein ähnliches Problem, obwohl ich eigentlich gar nicht weiß was das eigentliche Problem ist.
Ich möchte auch auf einer Homepage zyklisch Daten aktualisieren aus einer Textdatei, die im Minutentakt aktualisiert wird. Später auch Bilder, aber immer langsam.
Folgendes Script habe ich geschrieben. Lokal funktioniert das Script nur im Internetexplorer.

Hier das Script, hoffe es ist nicht zu lange:

Code:
var http = createRequestObject();
function createRequestObject() {
   var objAjax;
   var browser = navigator.appName;
   if(browser == "Microsoft Internet Explorer"){
      objAjax = new ActiveXObject("Microsoft.XMLHTTP");
   }else{
      objAjax = new XMLHttpRequest();

   }
   return objAjax;
}

function run(){


       file=http.open('post','vars/a');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_a').innerHTML = http.responseText;
            document.close()
            }




       file=http.open('post','vars/b');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_b').innerHTML = http.responseText;
            document.close()
            }




       http.open('post','vars/c');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_c').innerHTML = http.responseText;
            document.close()
            }



       http.open('post','vars/d');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_d').innerHTML = http.responseText;
            document.close()
            }




       http.open('post','vars/e');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_e').innerHTML = http.responseText;
            document.close()
            }




       http.open('post','vars/f');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_f').innerHTML = http.responseText;
            document.close()
            }
 



       http.open('post','vars/g');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_g').innerHTML = http.responseText;
            document.close()
            }
        


}


function update(){
setInterval(run,500);
return 0
}



Das Script funktioniert leider nur Lokal im Internetexplorer. Im Firebug kann man es allerdings Zeile für Zeile debuggen, dann aktualisiert es auch die Felder auf der Homepage, automatisch läuft es allerdings nicht. Ich habe es auch auf einen Apache2 server hoch geladen, so das die für das Script vorgesehene Homepage eine http adresse hat. Allerdings ging es auch nicht(Dachte das wäre das Kernproblem). Kann mir jemand sagen was ich grundsätzlich falsch mache? Wäre sehr dankbar.
viele Grüße
DumPNewbie
 
erstmal Entschuldigung, dass ich den alten Thread wieder ausgrabe als meine erste Handlung hier, aber thematisch habe ich ein ähnliches Problem, obwohl ich eigentlich gar nicht weiß was das eigentliche Problem ist.
Es ist vermutlich kein ähnliches Problem. Keiner hätte etwas dagegen gehabt, wenn du einen neuen Thread aufgemacht hast, so musste ich jetzt nochmal die alte Fragen lesen um rauszufinden, was und ob es etwas mit deiner Frage zu tun hat. Hat es aber nicht :(

Das Script funktioniert leider nur Lokal im Internetexplorer.
Was heißt lokal? Auf einem lokalen Server? Oder über das File:// Protokoll?
 
Ich Bitte um Entschuldigung. Javascript ist neu für mich, habe bisher hauptsächlich Python programmiert.

Genau, File// meinte ich mit Lokal, letztendlich soll es aber auf einem Server laufen.

Achja, es wird auf der HTML Seite über
HTML:
<body onload="javascript:update();">
geladen.
 
Hier das Script, hoffe es ist nicht zu lange:
da steht der gleiche code x mal hintereinander, nur mit unterschiedlichen parametern. dafür nutzt man normalerweise wenigstens funktionen.

Code:
   var browser = navigator.appName;
   if(browser == "Microsoft Internet Explorer"){
      objAjax = new ActiveXObject("Microsoft.XMLHTTP");
   }else{
      objAjax = new XMLHttpRequest();
   }
warum fragst du eine andere eigenschaft ab als du eigentlich nutzt? wenn du wissen willst, ob der Browser ActiveXObject ünterstützt, prüfe auf window.ActiveXObject und nicht ob navigator.appName irgendeiner zeichenkette entspricht. bei XMLHttpRequest das gleiche! ab IE7 gibt es z.b. beides.

Code:
       file=http.open('post','vars/a');
       http.send(null);
        if(http.readyState == 4){/* 4== laden erfolgreich */
            document.getElementById('var_a').innerHTML = http.responseText;
            document.close()
            }

dem XHR-Objekt kannst/musst du ein callback mitgeben, dieses wird aufgerufen, wenn sich der readyState ändert.
Das bei dir irgendwas geht ist reiner Zufall. du überschreibst ständig dein XHR-Objekt und wann der readyState rechtzeitig auf 4 wechselt bei welchem request ist nicht abzusehen (und überhaupt nur lokal möglich).
 
Zuletzt bearbeitet:
weiterhin verwendest du zwar POST (wieso eigentlich... du fragst doch daten vom Server ab, also wäre in deinem fall GET die bessere Variante) aber du setzt die header nicht auf www-form-urlencoded... das musst du noch machen oder überseh ich es nur?

Lg Kasalop
 
Das Hauptproblem ist file:// funktioniert im Firefox nicht, du musst zum testen einen lokalen Server einrichten.
Oder den IE9 oder Safari benutzen.

weiterhin verwendest du zwar POST (wieso eigentlich... du fragst doch daten vom Server ab, also wäre in deinem fall GET die bessere Variante)
POST hat den Vorteil, dass es nicht cached. Ich nutze GET deshalb garnicht mehr. Egal worum es geht. Die Unterscheidung nach Abfrage und Senden ist mit Ajax veraltet und nicht mehr relevant, da man heutzutage sowieso bei jedem Request etwas sendet und etwas abholt. Wo will man da noch einen Unterschied machen.
 
Zuletzt bearbeitet:
warum sollte das nicht funktionieren? ich kenne keinen browser mit dem das lokal nicht geht!
Hä? Ajax aus einer lokal aufgerufenen Datei?
Das funktioniert bei dir mit Browsern, die NICHT IE oder Safari heißen?
Wie hast du die dazu überredet?
Bei mir gelingt das nicht. Warum weiß ich zwar nicht aber es geht nicht.
Thema hatten wir letztens erst in einem anderen Thread. Führt immer wieder zu Verwirrung :)
Aber ich meine auch irgendwo gelesen zu haben, dass man beim Firefox die SOP in der Config irgendwo ausschalten kann. Dann ist natürlich klar, dass das geht.
 
Hä? Ajax aus einer lokal aufgerufenen Datei?
Das funktioniert bei dir mit Browsern, die NICHT IE oder Safari heißen?
gerade beim IE muss man darauf achten das man nicht das Browsereigene XHR-objekt nimmt, sondern das systemweite XHR-objekt. mindestens der IE7 hat probleme mit der SOP bei lokalen requests mit dem eigenem XHR-objekt.

Wie hast du die dazu überredet?
überhaupt nicht, die machen das einfach, warum auch nicht?


Aber ich meine auch irgendwo gelesen zu haben, dass man beim Firefox die SOP in der Config irgendwo ausschalten kann. Dann ist natürlich klar, dass das geht.
die SOP musst du schon beachten, sonst geht das nirgendwo. Also in einer lokalen Seite einen lokalen request starten geht, in einer seite von einem Server einen lokalen request starten geht natürlich nicht, auch nicht im IE.
 
Zurück
Oben