Thema: Ajax Manager

Hi,

Für alle, denen eine intensive Einarbeitung in Ajax zu umständlich ist, hab ich einen netten kleinen Manager aus meinem Projekt.

//---------------------------------- XML-Requests ------------------------------

//attempt, um doppelte Requests nicht nach doppelten Requests aussehen zu lassen
var attempt = 0;
//busy-Flag, um anzuzeigen, ob der XML-Prozess beschäftigt ist
var busy    = false;
//Array mit noch anstehenden Requests
var requests = new Array();

//Request-Klasse mit 
function RequestElement()
{
    this.url = "";
    this.fFunct = null;
    this.textMessage = false;    
}

//neuer Request wird angelegt
function newRequest(url, fFunct, textMessage)
{
    //Request-Element wird angelegt
    var request = new RequestElement();
    
    //mit Variablen belegt
    request.url         = url;
    request.fFunct      = fFunct;
    request.textMessage = textMessage;
    
    //und zurückgeliefert
    return request;
}

//ein Request wird der Liste hinzugefügt
function addRequest (url, fFunct, textMessage)
{
    //der Request wird an die Request-Liste angehängt
    requests.push (newRequest (url, fFunct, textMessage));
    
    //und ausgeführt
    executeRequests();
}

//alle Requests werden nacheinander ausgeführt
function executeRequests()
{
    //falls der Request noch beschäftigt ist
    if (busy)
    {
        //wird die Ausführung in 200 ms noch einmal versucht
        setTimeout ("executeRequests();", 200);    
        return;
    }
    
    //falls noch Requests vorhanden sind
    if (requests.length > 0)
    {
        //die Variablen werden ermittelt
        var url         = requests[0].url;
        var fFunct      = requests[0].fFunct;
        var textMessage = requests[0].textMessage;
        
        //und der Request ausgeführt
        request (url, fFunct, textMessage);
        
        //wird executeRequests nochmals ausgeführt
        executeRequests();
    }
    //sonst
    else
    {
        //wird die Funktion beendet
        return;    
    }
}

//ein Request wird gelöscht
function deleteRequest()
{
    //falls der Request bereits inaktiv ist
    if (!busy)
    {
        //wird nicht fortgefahren
        return;    
    }
    
    //der erste Request wird gelöscht
    requests.shift();    
    //und die Resourcen wieder freigegeben
    busy = false;
}

//Request-Verarbeitung
//fragt nach einer URL und gibt den Text bzw. die XML-Datei an die Folgefunktion weiter
//jede Folgefunktion muss im Format "function folge (XML-Daten, Text)" sein und Bool zurückliefern
function request (url, fFunct, textMessage)
{
    //falls ein anderer Request beschäftigt ist
    if (busy)
    {
        //wird nicht fortgefahren
        return false;    
    }
    
    //der Request wird beansprucht
    busy = true;
    
    //für Mozilla, Opera, usw.
    if (window.XMLHttpRequest) 
    {
        //Request wird angelegt
        http_request = new XMLHttpRequest();
        //Request wird angepasst, falls keine automatische Umformatierung stattfindet
           if (http_request.overrideMimeType) 
           {
            http_request.overrideMimeType('text/xml');
           }
    }
    //für IE
    else if (window.ActiveXObject)
    {
        //MSXML2 wird versucht
        try 
        {
            http_request = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.5.0");
        }
        //falls eine Ausnahme auftritt
        catch (e) 
        {
            //MSXML1 wird versucht
            try 
            {
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {}
        }
        
    }
    
    //falls der Request nicht exisitiert
    if (!http_request) 
    {
        //wird die Funktion beendet
        deleteRequest();
        return false;
    }
    
    //sobald der Request bearbeitet ist
    http_request.onreadystatechange = function()
    {
        //falls er vollständig abgearbeitet wurde
        if (http_request.readyState == 4) 
        {
               //falls kein Fehler beim Laden auftrat
            if (http_request.status == 200 || http_request.status == 304) 
            {
                //Daten werden bestimmt
                var data = http_request.responseXML;
                var text = http_request.responseText;
                
                //falls es sich nicht um einen Text handelt
                if (!textMessage)
                {
                    //falls kein Erfolgs-Tag vorhanden ist
                    if (data.getElementsByTagName ("success").item (0) == null)
                    {
                        //wird die Funktion beendet
                        deleteRequest();
                        return false;    
                    }
                
                    //die Variable für Erfolg wird geladen            
                    var success = data.getElementsByTagName ("success").item (0).firstChild.data;
                }
                //sonst
                else
                {
                    //ist kein XML-Objekt erforderlich
                    success = 1;    
                }
                
                //falls diese 1 ist
                if (success == 1)
                {
                    //wird zur angegebenen Funktion verzweigt
                    //falls diese erfolgreich war
                    if (fFunct (data, text))
                    {
                        //war die Ausführung erfolgreich
                        deleteRequest();
                        return true;    
                    }
                    //die Ausführung war nicht erfolgreich
                    deleteRequest();
                    return false;                
                }
                //sonst
                else
                {

                    //wird die Funktion beendet 
                    deleteRequest();
                    return false;
                }            
            }
            //sonst
            else
            {
                //wird die Funktion beendet
                deleteRequest();
                return false;    
            }
        }
        //sonst
        else
        {
            //wird die Funktion beendet
            return false;    
        }
    };
    
    //dem Request wird die URL mitgeteilt
    http_request.open('GET', url + "&attempt=" + (attempt + Math.random()), true);
    http_request.setRequestHeader ("Content-Type", "text/xml");
    
    //attempt-Zahl wird erhöht
    attempt++;
    
    //der Request wird versandt
    http_request.send ("");
    
    //die Ausführung war erfolgreich
    return true;
}

//Beispiel-Request-Funktion
//wird mit "request (url, exampleProcess)" ausgeführt
function exampleProcess (data, text)
{
    //der Text wird ausgegeben
    alert (text);
    
    //die Ausführung war erfolgreich
    return true;
}

//---------------------------------- /XML-Requests -----------------------------

Alles, was ihr hier tun müsst, ist, einen Request zu stellen. Das geschieht folgendermaßen

  addRequest (url, functionPointer, textMessage)

url ist die Url, die ihr anfordern wollt (WICHTIG: bitte immer ein "?" hinten anhängen!!!), functionPointer ist der FP für die Funktion, an die ihr die Daten übergeben wollt und textMessage ist eine bool-Variable, die festlegt, ob ihr nur Text oder auch das XML-Objekt braucht (false steht für XML-Objekt, true für alleinige Text-Message).

Die Folgefunktion sollte in der Form "function funct (data, text) {...}" angeben sein und mit einem bool-Wert zurückgeben, ob sie korrekt beendet wurde oder nicht.

Noch einige Sachen, die für die  XML-Datei wichtig sind:

- falls XML erwünscht ist, muss ein Feld <success>1</success> in der Datei stehen
- um im IE richtig zu funktionieren, muss bei PHP-Files der Header mit "header ("Content-type: text/xml");" gesetzt werden
- die Datei muss wohlgeformt sein, um akzeptiert zu werden
- browserabhängige Fehler treten nicht auf (z.B. wie beim IE ohne attempt-Variable)


Leistungsmerkmale der addRequest-Funktion:
- mehrere Requests können gestellt werden, ohne dass Ajax durcheinander kommt
- einfachste Handhabung, kein Gedanke muss mehr an Ajax verschwendet werden
- relativ einfacher Aufbau der Response Files möglich (auch Texte sind möglich)


Ich hoffe, ich kann einigen damit die Schikanen ersparen, die ich anfangs mit Ajax hatte.

Zuletzt bearbeitet von the-one (01-11-2005 01:04:27)

2

Re: Ajax Manager

Hallo,

ein sehr schöner Beitrag zu Ajax. Vielen Dank dafür!

vg
Hannes

_______________________________________________________________

/-/annes (j|g) ... http://www.jg-webdesign.de

Re: Ajax Manager

Ich habe nach dem ausgiebigen Nutzen des Ajax-Managers einige kleine Verbesserungsmöglichkeiten entdeckt, um die ich den Manager erweitert habe. Hier die neueste Version:

//---------------------------------- XML-Requests ------------------------------

//attempt, um doppelte Requests nicht nach doppelten Requests aussehen zu lassen
var attempt          = 0;
//busy-Flag, um anzuzeigen, ob der XML-Prozess beschäftigt ist
var busy             = false;
//Exception-Flag, um nur eine Exception auszugeben
var exceptionOccured = false;
//sollen die Exceptions ausgegeben werden?
var exceptionOutput  = true;
//Array mit noch anstehenden Requests
var requests         = new Array();

//Request-Klasse mit 
function RequestElement()
{
    this.url = "";
    this.fFunct = null;
    this.textMessage = false;    
}

//neuer Request wird angelegt
function newRequest(url, fFunct, textMessage)
{
    //Request-Element wird angelegt
    var request = new RequestElement();
    
    //mit Variablen belegt
    request.url         = url;
    request.fFunct      = fFunct;
    request.textMessage = textMessage;
    
    //und zurückgeliefert
    return request;
}

//ein Request wird der Liste hinzugefügt
function addRequest (url, fFunct, textMessage)
{
    //der Request wird an die Request-Liste angehängt
    requests.push (newRequest (url, fFunct, textMessage));
    
    //und ausgeführt
    executeRequests();
}

//alle Requests werden nacheinander ausgeführt
function executeRequests()
{
    //falls der Request noch beschäftigt ist
    if (busy)
    {
        //wird die Ausführung in 200 ms noch einmal versucht
        setTimeout ("executeRequests();", 200);    
        return;
    }

    //das Exception-Flag wird gelöscht
    exceptionOccured = false;
    
    //falls noch Requests vorhanden sind
    if (requests.length > 0)
    {
        //die Variablen werden ermittelt
        var url         = requests[0].url;
        var fFunct      = requests[0].fFunct;
        var textMessage = requests[0].textMessage;
        
        
        //und der Request ausgeführt
        try
        {
            request (url, fFunct, textMessage);
        }
        //falls ein Fehler auftritt
        catch (e)
        {
            //wird die Fehlermeldung ausgegeben
            alert ("Exception (" + url + "):\n" + e);    
        }
        
        //wird executeRequests nochmals ausgeführt
        executeRequests();
    }
    //sonst
    else
    {
        //wird die Funktion beendet
        return;    
    }
}

//ein Request wird gelöscht
function deleteRequest()
{
    //falls der Request bereits inaktiv ist
    if (!busy)
    {
        //wird nicht fortgefahren
        return;    
    }

    //der erste Request wird gelöscht
    requests.shift();    
    //und die Resourcen wieder freigegeben
    busy = false;
}

//Request-Verarbeitung
//fragt nach einer URL und gibt den Text bzw. die XML-Datei an die Folgefunktion weiter
//jede Folgefunktion muss im Format "function folge (XML-Daten, Text)" sein und Bool zurückliefern
function request (url, fFunct, textMessage)
{
    //falls ein anderer Request beschäftigt ist
    if (busy)
    {
        //wird nicht fortgefahren
        return false;    
    }
    
    //der Request wird beansprucht
    busy = true;
    
    //für Mozilla, Opera, usw.
    if (window.XMLHttpRequest) 
    {
        //Request wird angelegt
        http_request = new XMLHttpRequest();
        //Request wird angepasst, falls keine automatische Umformatierung stattfindet
           if (http_request.overrideMimeType) 
           {
            http_request.overrideMimeType('text/xml');
           }
    }
    //für IE
    else if (window.ActiveXObject)
    {
        //MSXML1 wird versucht
        try 
        {
            http_request = new ActiveXObject("Microsoft.XMLHTTP");
        }
        //falls eine Ausnahme auftritt
        catch (e) 
        {}
    }
    
    //falls der Request nicht exisitiert
    if (!http_request) 
    {
        
        deleteRequest();
        //eine Exception wird geworfen
        throw "Bad HTTP Request";
        //die Funktion wird beendet
        return false;
    }
    
    //sobald der Request bearbeitet ist
    http_request.onreadystatechange = function()
    {
        //die Funktion wird versucht
        try
        {
            //falls er vollständig abgearbeitet wurde
            if (http_request.readyState == 4) 
            {
                
                   //falls kein Fehler beim Laden auftrat
                if (http_request.status == 200 || http_request.status == 304) 
                {
                    //Daten werden bestimmt
                    var data = http_request.responseXML;
                    var text = http_request.responseText;
                    
                    //falls es sich nicht um einen Text handelt
                    if (!textMessage)
                    {
                        //falls kein Erfolgs-Tag vorhanden ist
                        if (data.getElementsByTagName ("success").item (0) == null)
                        {
                            //wird der Request gelöscht
                            deleteRequest();
                            //eine Exception wird geworfen
                            throw "No success Tag defined";
                            //die Funktion wird beendet
                            return false;    
                        }
                    
                        //die Variable für Erfolg wird geladen            
                        var success = data.getElementsByTagName ("success").item (0).firstChild.data;
                    }
                    //sonst
                    else
                    {
                        //ist kein XML-Objekt erforderlich
                        success = 1;    
                    }
                    
                    //falls diese 1 ist
                    if (success == 1)
                    {
                        //wird zur angegebenen Funktion verzweigt
                        //falls diese erfolgreich war
                        if (fFunct (data, text))
                        {
                            //war die Ausführung erfolgreich
                            deleteRequest();
                            return true;    
                        }
                        //die Ausführung war nicht erfolgreich
                        deleteRequest();
                        //eine Exception wird geworfen
                        throw "An error occured during execution of fFunction";
                        //die Funktion wird beendet
                        return false;                
                    }
                    //sonst
                    else
                    {
                        //wird der Request gelöscht 
                        deleteRequest();
                        //eine Exception wird geworfen
                        throw "Success Tag incorrect";
                        //die Funktion wird beendet
                        return false;
                    }            
                }
                //sonst
                else
                {
                    //der Request gelöscht
                    deleteRequest();
                    //eine Exception wird geworfen
                    throw "HTTP Error No. " + http_request.status + " occured";
                    //die Funktion wird beendet
                    return false;    
                }
            }
            //sonst
            else
            {
                //die Funktion wird beendet
                return false;    
            }
        }
        //falls ein Fehler auftritt
        catch (e)
        {
            //falls der Fehler eine Exception ist
            if (typeof e == 'string')
            {    
                //falls noch keine Exception aufgetreten ist    
                if (!exceptionOccured)
                {
                    //ist nun eine Exception aufgetreten
                    exceptionOccured = true;
                    //falls die Exception ausgegeben werden soll
                    if (exceptionOutput)
                    {
                        //die Exception wird ausgegeben
                        alert ("Exception (" + url + "):\n" + e);
                    }
                }
            }
        }    

    };
    
    //dem Request wird die URL mitgeteilt
    http_request.open('GET', url + "&attempt=" + (attempt + Math.random()), true);
    http_request.setRequestHeader ("Content-Type", "text/xml");
    
    //attempt-Zahl wird erhöht
    attempt++;
    
    //der Request wird versandt
    http_request.send ("");
    
    //die Ausführung war erfolgreich
    return true;
}


//Request-Funktion für reine Actions (tut nichts)
//wird mit "request (url, doNothing)" ausgeführt
function doNothing (data, text)
{
    return true;    
}

//Beispiel-Request-Funktion
//wird mit "request (url, exampleProcess)" ausgeführt
function exampleProcess (data, text)
{
    //der Text wird ausgegeben
    alert (text);
    
    //die Ausführung war erfolgreich
    return true;
}

//---------------------------------- /XML-Requests -----------------------------

Verbesserungen:
- falls ein Fehler in der Ausührung des Requests auftrat, wird dieser ausgegeben (falls exceptionOutput auf true gesetzt ist)
- der Prozess "doNothing" tut nichts (für ActionURL's sinnvoll)

Re: Ajax Manager

Hey cool, werde ich wohl die woche noch testen.