Ajax in Modul, Fehler Joomla

=fire=

Erfahrenes Mitglied
Guten Tag,

ich habe mir ein Modul geschrieben das einfach nur immer den Datenbank eintrag anzeigen soll.

Leider kommt der Fehler:

Der Request wurde abgeschlossen, ist aber nicht OK
Fehler:404

Sobald ich das Script direkt aufrufe kommt der Fehler nicht. Dann klappt alles prima.

Ich habe das Module mit {module AJAX} in den Artikel der Startseite eingebunden.

Das Script:
mod_AJAX.php
HTML:
<script type="text/javascript">
  <!--
      var aktiv = window.setInterval("setRequest()", 1000);
    var request = false;

    // Request senden
    function setRequest() {
        // Request erzeugen
        if (window.XMLHttpRequest) {
            request = new XMLHttpRequest(); // Mozilla, Safari, Opera
        } else if (window.ActiveXObject) {
            try {
                request = new ActiveXObject('Msxml2.XMLHTTP'); // IE 5
            } catch (e) {
                try {
                    request = new ActiveXObject('Microsoft.XMLHTTP'); // IE 6
                } catch (e) {}
            }
        }

        // überprüfen, ob Request erzeugt wurde
        if (!request) {
            alert("Kann keine XMLHTTP-Instanz erzeugen");
            return false;
        } else {
            var url = "current.php";
            // Request öffnen
            request.open('post', url, true);
            // Request senden
            request.send(null);
            // Request auswerten
            request.onreadystatechange = interpretRequest;
        }
    }

    // Request auswerten
    function interpretRequest() {
        switch (request.readyState) {
            // wenn der readyState 4 und der request.status 200 ist, dann ist alles korrekt gelaufen
            case 4:
                if (request.status != 200) {
                    alert("Der Request wurde abgeschlossen, ist aber nicht OK\nFehler:"+request.status);
                } else {
                    var content = request.responseText;
                    // den Inhalt des Requests in das <div> schreiben
                    document.getElementById('content').innerHTML = content;
                }
                break;
            default:
                break;
        }
    }
  //-->
  </script>
  <div id="content"></div>

current.php
PHP:
<?php
header('Content-Type: text/html; charset=utf-8'); // sorgt für die korrekte Kodierung
header('Cache-Control: must-revalidate, pre-check=0, no-store, no-cache, max-age=0, post-check=0'); // ist mal wieder wichtig wegen IE
include('config.php');
$sql = mysql_query("SELECT u.username FROM jos_users as u LEFT JOIN jos_sl_bit as b ON u.id=b.user_id WHERE b.article_id='".$id."' ORDER by b.bit_id DESC LIMIT 1", $verbindung);

$row1 = mysql_fetch_array($sql);
echo $row1['username'];
?>


Vielen Dank im voraus, Gruß fire
 
Moin,

der Fehlertext ist ja eindeutig....der Pfad stimmt nicht.

Falls du Firebug nutzt, schaue mal im Netzwerktab nach, dort sollte der komplette Pfad stehen, der angefragt wird....und dich der Lösung näher bringen.

Ein Verzicht auf relative Pfade wäre dabei wohl das sicherste.
 
Firesimon hat gesagt.:
Wenn ich auf der Seite auf ein Link oder Button klicke kommt manchmal

Der Request wurde abgeschlossen, ist aber nicht OK
Fehler: ()

Woran es da hapert, kann ich ohne mehr Details nicht sagen.
Das Skript prüft ja, ob dort mit einem HTTP-Statuscode 200 geantwortet wird, und sieht alles andere als Fehler an(was nicht unbedingt sein muss)

Wenn der Status 404 ist, dann stimmt halt der Pfad nicht...welche Statuscodes bekommst du denn bei den Links&Buttons?


Was das nicht funktionierende betrifft:
JS-Code in Antworten von AJAX-Requests wird nicht gezwungenermassen interpretiert, auch nicht, wenn man ihn per innerHTML ins Dokument einfügt.
Selbst wenn es so wäre, wird deine Aktion ja beim onload angestossen:
Code:
window.onload = function () {
          new countdown();
    };
...dieser Zeitpunkt ist zu dem Moment, wo die Antwort vom Server kommt, jedoch höchstwahrscheinlich verstrichen.

Ich würde so herangehen:
Lese in der current.php die Daten(Jahr, Monat, etc) aus, und gebe sie als JSON-String aus. Die Daten kannst du dann im anfragenden Skript wieder verarbeiten, z.B. indem du sie der (auch im anfragenden Skript notierten Funktion countdown) als Parameter übergibst.
 
Jo, kann ich.

Erzähl doch erstmal ein paar Details über deine Anwendung :)

Du hast da den Countdown.... soll das immer nur einer bleiben pro Seite, oder auch mal mehr.

Der Countdown soll ja, soweit ich es verstanden habe, die restliche Laufzeit einer Auktion anzeigen...warum holst du bspw. das Enddatum per AJAX ab, und nicht direkt in dem Skript?
 
Hi,

richtig. Das Enddatum der Auktion lese ich mit PHP aus. Da sich das Datum in der datenbank aber ändern kann soll AJAX überprüfen ob ein neues Datum vorhanden ist ohne das die Seite aktualisiert werden muss.

Mfg Simon
 
Firesimon hat gesagt.:
Das ist nur ein Countdown.

Mir doch egal:p :suspekt:

Hier eine Variante, die mit mehreren Countdowns umgehen kann(nicht erschrecken, sieht vielleicht anfangs nach sehr viel aus)
Code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; 
                                charset=utf-8"   />
<meta name="author"             content="doktormolle" />
<meta name="date"               content="2009-07-13" />
<title>Test</title>
<script type="text/javascript">
<!--
AJAX=function(args)
{
      //das Basis-Objekt:
    var ajax = args;

  /**
    * Erweiterung des Basis-Objektes 
    * um die Methode zum Ausführen des Requests
    **/
  ajax.request = function() 
  {
    try{
    
            //Erstellen [XMLHttpRequest]-Objekt
          this.xhr = window.XMLHttpRequest
                    ? new XMLHttpRequest()
                    : new ActiveXObject("Microsoft.XMLHTTP"); 
			  
            //Setzen der Übermittlungsmethode
          this.method=(typeof this.method == 'undefined')
                        ? 'GET'
                        : this.method;
			  
            //Aufbereiten der Daten		
          this.data=(this.data || '');
			  
          this.postData=(this.method=='GET')
                          ? null
                          : this.data;
			            
            //Aufbereiten der URL			                   
          this.URL=(this.method=='POST' || this.data=='')
                      ? this.URL
                      : (
                          (this.URL.indexOf('?')==-1)
                            ? this.URL+'?'+this.data
                            : this.URL+'&'+this.data
                          );
			   
            //Initialisieren des Requests
          this.xhr.open(this.method,this.URL,true);
			  
            //Senden den bei POST erforderlichen Request-Header     
          if(this.method=='POST')
            {
              this.xhr.setRequestHeader("Content-type", 
                                        "application/x-www-form-urlencoded");
              this.xhr.setRequestHeader("Content-length", 
                                         this.postData.length);
              this.xhr.setRequestHeader("Connection", 
                                        "close");
            }
			    
            //Bei Bedarf Nutzung des Cache verhindern
          if(!typeof this.nocache || this.nocache)
            {
              this.xhr.setRequestHeader("If-Modified-Since",
                                        "Thu, 01 Jan 1970 00:00:00 GMT");
            }
			  
            //Zuweisen der verarbeitenden Funktion
          if(typeof this.callback == 'function')
          {
            this.xhr.onreadystatechange = 
                                  function()
                                  { 
                                    
                                    var r=ajax.xhr.readyState;
                                    var s=(r==4)?ajax.xhr.status:null
                                    ajax.callback(ajax,r,s);
                                      
                                  };
          }

            //Senden   
          this.xhr.send(this.postData);    
    }
    catch(e)
    {
      try{console.log('Fehler:AJAX.request()');}
      catch(e){}
    }
  
    
  }
	
      //Rückgabe Basis-Objekt
    return ajax;
}



Number.prototype.formatSpareTime=function(f)
{
  sec=this;
  var t={'d':0,'h':0,'m':0,'s':0};
  t.d=Math.floor(sec/86400);
  sec=sec%86400;
  t.h=Math.floor(sec/3600);
  sec=sec%3600;
 t.m=Math.floor(sec/60);
  t.s=sec%60;
  var r=[];
  for(var k in f)
  {
    if(t[k] || !f[k][4])
    {
      a=(t[k]<10)
          ? [(t[k]===1)
                  ? f[k][1]
                  : f[k][0],
              (f[k][3])
                  ? '0'+t[k]
                  : t[k]
            ]
          : [f[k][0],t[k]]
      
      if(f[k][1]){a.reverse()}
      r.push(a.join(' '));
      
    }
  }
  return(r.join(''));
}

function countdown_artikel()
{
  
  ajax=countdown_artikel.arguments[0];
  request=ajax.xhr;
  if(ajax.xhr.readyState==4)
  {
    window[ajax.prefix+ajax.artikelid]=
    {
    'ajax':ajax,
    'format':{'d':['Tage,','Tag,',1,0,1],
              'h':['Stunden:','Stunden:',1],
              'm':[':',':',1,1],
              's':['','',1,1]
             },
    'start':Math.floor(new Date().getTime()/1000),
    'i':0,
    timer:function()
            {
              elapsed=Math.floor(new Date().getTime()/1000)-this.start;
              spare=this.end-elapsed;
              if(spare<0)
              {
                this.target.innerHTML="die Auktion ist beendet";
              }
              else
              {
                this.i++;
               
                if(this.i%this.ajax.refresh==0)
                {
                  AJAX(this.ajax).request();
                }
                else
                {
                  window.setTimeout(this.id+".timer()",this.ajax.interval);
                }
                 this.target.innerHTML=Number(spare).formatSpareTime(this.format);
              }
            },
    'init':function()
            {
            
              this.id=this.ajax.prefix+this.ajax.artikelid;
              this.target=document.getElementById(this.id);
              this.end=this.ajax.xhr.responseText;
              window.setTimeout(this.id+".timer()",this.ajax.interval);
              return this;
            }
     
    }.init();
  }
  
}

//-->
</script>
<style type="text/css">
<!--
-->
</style>
</head>
<body>
<div id="countdown4711"></div>
<script type="text/javascript">
<!--
AJAX(
      {'method':'POST',
       'artikelid':'4711',
       'prefix':'countdown',
       'interval':1000,
       'refresh':10,
       'data':'artikelid='+4711,
       'URL':'current.php',
       'callback':countdown_artikel}
).request();
//-->
</script>
<div id="countdown4712"></div>
<script type="text/javascript">
<!--
AJAX(
      {'method':'POST',
       'artikelid':'4712',
       'prefix':'countdown',
       'interval':1000,
       'refresh':10,
       'data':'artikelid='+4712,
       'URL':'current.php',
       'callback':countdown_artikel}
).request();
//-->
</script>
<div id="countdown4713"></div>
<script type="text/javascript">
<!--
AJAX(
      {'method':'POST',
       'artikelid':'4713',
       'prefix':'countdown',
       'interval':1000,
       'refresh':10,
       'data':'artikelid='+4713,
       'URL':'current.php',
       'callback':countdown_artikel}
).request();
//-->
</script>


</body>
</html>

Erstmal ein paar Grundgedanken:
  1. Deine bisherige AJAX-Lösung kann nur mit einem einzigen Request gleichzeitig umgehen, ich nutze daher eine andere Möglichkeit, die Beschreibung dazu findest du hier: http://www.tutorials.de/forum/javas...x-http-requests-unter-kontrolle-behalten.html
  2. Du hast da serverseitig ein Datum gespeichert, und benutzt das zu Berechnungen in JS...da gibt es ein grosses Problem: JS arbeitet mit der Clientzeit und nicht mit der Serverzeit.
    Bei einem Besucher aus Peking wird die Auktion somit(zumindest in der Ausgabe im Browser) früher beendet sein, als bei einem Besucher aus Rio.
    Daher erwartet meine Lösung nicht eine Datumsangabe, sondern eine Zeitdifferenz(in Sekunden) bis zum Ablauf der Auktion.
    Du müsstest also serverseitig von dem in der DB gespeicherten Timestamp die aktuelle Server-Zeit abziehen.

Noch ein paar Erläuterungen zum Aufruf:

Code:
<div id="countdown4711"></div>
<script type="text/javascript">
<!--
AJAX(
      {'method':'POST',
       'artikelid':'4711',
       'prefix':'countdown',
       'interval':1000,
       'refresh':10,
       'data':'artikelid='+4711,
       'URL':'current.php',
       'callback':countdown_artikel}
).request();
//-->
</script>
Die Parameter:
  • method:sollte klar sein
  • artikelid: du fragst ja einen Artikel aus der DB ab...hier gebe seine ID an
  • prefix:da auch mehrere Countdowns möglich sein sollen, gebe hier ein Prefix an, welches der ID des Countdowns vorrangestellt wird(du siehst das an der ID des <div>...countdown4711, diese setzt sich aus dem Prefix und der Artikel-ID zusammen, so findet jeder Countdown sein richtiges Zielelement)
  • interval: die Millisekunden, nach denen der Coundown aktualisiert werden soll(Werte unter 1000 sind da eigentlich sinnlos, da du ja eh nur Sekundenschritte anzeigst)
  • refresh: Zähler, der angibt, nach wievielen Intervallen per AJAX auf dem Server nachgeschaut werden soll, ob sich am Endtermin etwas geändert hat.
    Mit der Einstellung dort von 10 und dem Interval von 1000 wäre das also alle 10 Sekunden(übertreibs dort nicht, so ein Server ist auch nur ein Mensch, und dort jede Sekunde einen Request abzuschicken, kann ihn bei vielen Besuchern recht sauer machen ;) )
  • data: das sind die Daten, die gesendet werden sollen, im Beispiel würde ein $_POST['artikelid'] mit dem Wert 4711 an den Server gesendet...also die Artikel-ID für die DB-Abfrage.
  • URL: sollte klar sein
  • callback: die Funktion, die die Coundowns erstellt und das ganze Aktualisieren übernimmt...du findest sie im Code.

Das wärs...falls du Fragen hast, frag(aber nicht heute, ich bin erst nachts wieder daheim :) )
 
Hallo,

wie sollen denn dann die PHP Datei aussehen? einfach nur das Datum mit echo ausgeben?

Mfg Simon
 
Okay, das klappt wunderbar danke. Kann man da noch was ergänzen das sobald der Countdown = 0 ist eine PHP Datei ausgeführt wird?

Mfg Simon
 
Zuletzt bearbeitet:
Zurück