Für viele Webentwickler reicht es aus, einfache Anfragen zu generieren und einfache Antworten zu erhalten. Für Entwickler, die Ajax beherrschen möchten, ist jedoch ein umfassendes Verständnis der HTTP-Statuscodes, der Bereitschaftszustände und des XMLHttpRequest-Objekts erforderlich. In diesem Artikel stellt Ihnen Brett McLaughlin die verschiedenen Statuscodes vor und zeigt Ihnen, wie Browser damit umgehen. Er geht auch auf einige der weniger häufigen HTTP-Anfragen ein, die in Ajax verwendet werden.
Im vorherigen Artikel dieser Serie haben wir uns das XMLHttpRequest-Objekt genauer angesehen, das das Herzstück einer Ajax-Anwendung darstellt und für die Verarbeitung von Anfragen von serverseitigen Anwendungen und Skripten sowie für die Verarbeitung von Daten verantwortlich ist, die von serverseitigen Komponenten zurückgegeben werden. Da alle Ajax-Anwendungen das XMLHttpRequest-Objekt verwenden, möchten Sie sich möglicherweise mit diesem Objekt vertraut machen, damit Ajax eine bessere Leistung erbringen kann.
In diesem Artikel werde ich mich auf die drei Hauptteile dieses Anforderungsobjekts konzentrieren, die auf dem vorherigen Artikel basieren:
· HTTP-Bereitschaftsstatus · HTTP-Statuscode · Die Anforderungstypen, die generiert werden können.
Diese drei Teile sind alle bei der Erstellung eines zu berücksichtigenden Faktors Auf Anfrage wurde zu diesen Themen jedoch zu wenig geschrieben. Wenn Sie jedoch mehr als nur die Grundlagen der Ajax-Programmierung erlernen möchten, müssen Sie sich mit den Inhalten der Bereitschaftszustände, Statuscodes und den Anforderungen selbst vertraut machen. Wenn mit Ihrer Anwendung etwas schief geht – und das passiert immer –, können Sie das Problem in 5 Minuten beheben, wenn Sie den Bereitschaftsstatus richtig verstehen, wie eine HEAD-Anfrage generiert wird oder was genau ein 400-Statuscode bedeutet, anstatt 5 Stunden aufzuwenden in verschiedenen Frustrationen und Verwirrungen.
Schauen wir uns zunächst den HTTP-Bereitschaftsstatus an.
Ein genauerer Blick auf den HTTP-Bereitschaftsstatus.
Sie werden sich aus dem vorherigen Artikel erinnern, dass das XMLHttpRequest-Objekt eine Eigenschaft namens readyState hat. Dieses Attribut stellt sicher, dass der Server eine Anfrage abgeschlossen hat, indem es normalerweise eine Rückruffunktion verwendet, um Daten vom Server zu lesen und den Inhalt des Webformulars oder der Seite zu aktualisieren. Listing 1 zeigt ein einfaches Beispiel (es ist auch ein Beispiel aus dem vorherigen Artikel dieser Serie – siehe Ressourcen).
XMLHttpRequest oder XMLHttp: Eine Namensänderung
Microsoft™ und Internet Explorer verwenden ein Objekt namens XMLHttp anstelle des XMLHttpRequest-Objekts, das von Mozilla, Opera, Safari und den meisten Nicht-Microsoft-Browsern verwendet wird. Der Einfachheit halber nenne ich beide Objekte einfach XMLHttpRequest. Dies steht sowohl im Einklang mit dem, was wir im Web sehen, als auch mit der Absicht von Microsoft, XMLHttpRequest als Anforderungsobjekt in Internet Explorer 7.0 zu verwenden. (Weitere Informationen zu diesem Thema finden Sie in Teil 2.)
Listing 1. Umgang mit der Antwort des Servers in einer Rückruffunktion
updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var Response = request.responseText.split("|");
document.getElementById("order").value = Response[0];
document.getElementById("address").innerHTML =
Antwort[1].replace(/n/g, "<br />");
} anders
Alert("Status ist " + request.status);
}
}
Dies ist offensichtlich die häufigste (und einfachste) Verwendung des Bereitschaftszustands. Wie Sie an der Zahl „4“ erkennen können, gibt es mehrere weitere Bereitschaftszustände (diese Liste haben Sie auch im vorherigen Artikel gesehen – siehe Ressourcen):
· 0: Die Anfrage ist nicht initialisiert ( open() wurde noch nicht aufgerufen) .
·1: Die Anfrage wurde hergestellt, aber nicht gesendet (send() wurde noch nicht aufgerufen).
·2: Die Anfrage wurde gesendet und wird verarbeitet (normalerweise können die Inhaltsheader jetzt aus der Antwort abgerufen werden).
·3: Die Anfrage wird verarbeitet; normalerweise sind einige Daten in der Antwort verfügbar, aber der Server hat die Generierung der Antwort noch nicht abgeschlossen.
·4: Die Antwort ist vollständig; Sie können die Antwort des Servers abrufen und verwenden.
Wenn Sie mehr als nur die Grundlagen der Ajax-Programmierung verstehen möchten, müssen Sie nicht nur diese Zustände kennen, sondern auch, wann sie auftreten und wie man sie verwendet. Zunächst müssen Sie herausfinden, welche Anforderungszustände in den einzelnen Bereitschaftszuständen auftreten können. Leider ist dies nicht intuitiv und beinhaltet mehrere Sonderfälle.
Versteckter Bereitschaftszustand
Der erste Bereitschaftszustand ist dadurch gekennzeichnet, dass das Attribut „readyState“ 0 ist (readyState == 0), was einen nicht initialisierten Zustand anzeigt. Diese Eigenschaft wird auf 1 gesetzt, sobald open() für das Anforderungsobjekt aufgerufen wird. Da Sie open() normalerweise unmittelbar nach der Initialisierung eines Anforderungspaars aufrufen, werden Sie selten den Status „readyState == 0“ sehen. Darüber hinaus hat der nicht initialisierte Bereitschaftszustand in realen Anwendungen keinen wirklichen Nutzen.
Aber für unser Interesse sehen Sie sich Listing 2 an, das zeigt, wie man diesen Bereitschaftszustand erhält, wenn readyState auf 0 gesetzt ist.
Listing 2. 0-Bereitschaftsstatus wird erreicht
Funktion getSalesData() {
//Erstelle ein Anforderungsobjekt
createRequest();
Alert("Bereitschaftsstatus ist: " + request.readyState);
// Richten Sie die Anforderung ein (initialisieren).
var url = "/boards/servlet/UpdateBoardSales";
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
In diesem einfachen Beispiel ist getSalesData() die Funktion, die die Webseite aufruft, um eine Anfrage zu initiieren (z. B. wenn auf eine Schaltfläche geklickt wird). Beachten Sie, dass Sie den Bereitschaftsstatus überprüfen müssen, bevor Sie open() aufrufen. Abbildung 1 zeigt die Ergebnisse der Ausführung dieser Anwendung.
Abbildung 1. Bereitschaftszustand 0
Offensichtlich bringt Ihnen das nicht viel; es gibt nur sehr wenige Situationen, in denen Sie sicherstellen müssen, dass die Funktion open() noch nicht aufgerufen wurde. In der realen Welt der meisten Ajax-Programmierungen besteht die einzige Verwendung dieses Bereitschaftszustands darin, dasselbe XMLHttpRequest-Objekt zu verwenden, um mehrere Anforderungen über mehrere Funktionen hinweg zu generieren. In diesem (ungewöhnlichen) Fall möchten Sie möglicherweise sicherstellen, dass sich das Anforderungsobjekt in einem nicht initialisierten Zustand (readyState == 0) befindet, bevor Sie eine neue Anforderung generieren. Dadurch wird im Wesentlichen sichergestellt, dass nicht gleichzeitig eine andere Funktion das Objekt verwendet.
Zeigen Sie den Bereitschaftsstatus der verarbeiteten Anforderung an
. Zusätzlich zum Bereitschaftsstatus 0 muss das Anforderungsobjekt auch mehrere andere Bereitschaftsstatus typischer Anforderungen und Antworten durchlaufen und endet schließlich in Form von Bereitschaftsstatus 4. Aus diesem Grund wird in den meisten Rückruffunktionen die Zeile if (request.readyState == 4) angezeigt. Sie stellt sicher, dass der Server die Verarbeitung der Anforderung abgeschlossen hat und die Webseite jetzt sicher aktualisiert werden kann oder die Seite basierend auf der zurückgegebenen Anforderung aktualisiert werden kann vom Server.
Es ist sehr einfach zu erkennen, wie dieser Zustand auftritt. Wenn der Bereitschaftsstatus 4 ist, müssen wir nicht nur den Code in der Rückruffunktion ausführen, sondern wir drucken auch den Bereitschaftsstatus jedes Mal aus, wenn die Rückruffunktion aufgerufen wird. Listing 3 zeigt ein Beispiel für die Implementierung dieser Funktionalität.
Wenn 0 gleich 4 ist
, müssen Sie den Bereitschaftsstatus 0 überprüfen, um sicherzustellen, dass das Anforderungsobjekt nicht verwendet wird, wenn mehrere JavaScript-Funktionen dasselbe Anforderungsobjekt verwenden. Dieser Mechanismus kann Probleme verursachen. Da readyState == 4 eine abgeschlossene Anfrage darstellt, werden Sie häufig feststellen, dass Anfrageobjekte im Bereitschaftszustand, die derzeit nicht verwendet werden, immer noch auf 4 gesetzt sind – dies liegt daran, dass die vom Server zurückgegebenen Daten bereits verwendet wurden, aber nicht Es wurden Änderungen vorgenommen, seit sie in den Bereitschaftszustand versetzt wurden. Es gibt eine Funktion abort(), die das Anforderungsobjekt zurücksetzt, diese Funktion wird jedoch nicht wirklich für diesen Zweck verwendet. Wenn Sie mehrere Funktionen verwenden müssen, ist es besser, für jede Funktion eine Funktion zu erstellen und zu verwenden, anstatt dasselbe Objekt für mehrere Funktionen gemeinsam zu nutzen.
Listing 3. Bereitschaftsfunktion
updatePage() {
anzeigen
// Den aktuellen Bereitschaftszustand ausgeben
alarm("updatePage() aufgerufen mit Bereitschaftsstatus " + request.readyState);
}
Wenn Sie nicht sicher sind, wie diese Funktion ausgeführt wird, müssen Sie eine Funktion erstellen, diese Funktion dann auf der Webseite aufrufen und eine Anfrage an die serverseitige Komponente senden lassen (z. B. die in Listing 2 gezeigte Funktion oder). die Funktion in dieser Artikelserie) Beispiele in Teil 1 und Teil 2). Stellen Sie sicher, dass Sie die Callback-Funktion auf updatePage() setzen, wenn Sie die Anfrage stellen. Setzen Sie dazu die Eigenschaft onreadystatechange des Anfrageobjekts auf updatePage().
Dieser Code ist eine genaue Demonstration der Bedeutung von onreadystatechange – jedes Mal, wenn sich der Bereitschaftsstatus der Anfrage ändert, wird updatePage() aufgerufen, und dann wird eine Warnung angezeigt. Abbildung 2 zeigt ein Beispiel für den Aufruf dieser Funktion, wobei der Bereitschaftsstatus 1 ist.
Abbildung 2. Bereitschaftszustand 1
Sie können versuchen, diesen Code selbst auszuführen. Fügen Sie es in eine Webseite ein und aktivieren Sie den Ereignishandler (klicken Sie auf eine Schaltfläche, wechseln Sie mit der Tabulatortaste zwischen Feldern oder verwenden Sie die von Ihnen festgelegte Methode, um die Anforderung auszulösen). Diese Rückruffunktion wird mehrmals ausgeführt – jedes Mal, wenn sich der Bereitschaftsstatus ändert – und Sie können die Warnung für jeden Bereitschaftsstatus sehen. Dies ist die beste Möglichkeit, die verschiedenen Phasen zu verfolgen, die eine Anfrage durchläuft.
Browser-Inkonsistenzen
Nachdem Sie den Vorgang grundsätzlich verstanden haben, versuchen Sie, mit mehreren verschiedenen Browsern auf Ihre Seite zuzugreifen. Sie sollten beachten, dass Browser diese Bereitschaftszustände inkonsistent handhaben. In Firefox 1.5 würden Sie beispielsweise die folgenden Bereitschaftszustände sehen:
·1
·2
·3
·4
Dies ist nicht überraschend, da hier jeder Anforderungsstatus dargestellt wird. Wenn Sie jedoch Safari verwenden, um auf dieselbe Anwendung zuzugreifen, sollten Sie etwas Interessantes sehen – oder auch nicht. So sieht es in Safari 2.0.1 aus:
·2
·3
·4
Safari verwirft tatsächlich den ersten Bereitschaftsstatus, und es gibt keinen offensichtlichen Grund dafür, aber so funktioniert Safari einfach. Dies verdeutlicht auch einen wichtigen Punkt: Während es eine gute Idee ist, sicherzustellen, dass der Anforderungsstatus 4 ist, bevor die Daten auf dem Server verwendet werden, sieht Code, der so geschrieben wurde, dass er sich auf jeden Übergangsbereitschaftsstatus verlässt, bei verschiedenen Browsern tatsächlich anders aus.
Bei Verwendung von Opera 8.5 ist der angezeigte Bereitschaftsstatus beispielsweise noch schlechter:
·3
·
4Abschließend zeigt Internet Explorer den folgenden Status an:
·1
·2
·3
·4Wenn
Sie Probleme mit Ihren Anfragen haben, ist dies die erste Anlaufstelle, um das Problem zu identifizieren. Am besten testen Sie dies sowohl im Internet Explorer als auch in Firefox – Sie sehen alle vier Status und können überprüfen, in welchem Status sich die Anfrage befindet.
Schauen wir uns als Nächstes die Situation auf der Antwortseite an.
Antwortdaten unter der Lupe
Sobald wir die verschiedenen Bereitschaftszustände verstanden haben, die während des Anforderungsprozesses auftreten, ist es an der Zeit, einen weiteren Aspekt des XMLHttpRequest-Objekts zu betrachten – das Attribut „responseText“. Erinnern Sie sich an das, was wir im vorherigen Artikel vorgestellt haben. Sie können wissen, dass dieses Attribut zum Abrufen von Daten vom Server verwendet wird. Sobald der Server die Verarbeitung der Anfrage abgeschlossen hat, kann er alle zur Beantwortung der Anfrage erforderlichen Daten in den Antworttext der Anfrage einfügen. Die Callback-Funktion kann diese Daten dann verwenden, wie in Listing 1 und Listing 4 gezeigt.
Listing 4. Verwenden der auf dem Server zurückgegebenen Antwort
Funktion updatePage() {
if (request.readyState == 4) {
var newTotal = request.responseText;
var totalSoldEl = document.getElementById("total-sold");
var netProfitEl = document.getElementById("net-profit");
replaceText(totalSoldEl, newTotal);
/* Stellen Sie sich den neuen Nettogewinn vor */
var boardCostEl = document.getElementById("board-cost");
var boardCost = getText(boardCostEl);
var manCostEl = document.getElementById("man-cost");
var manCost = getText(manCostEl);
var profitPerBoard = boardCost - manCost;
var netProfit = profitPerBoard * newTotal;
/* Nettogewinn im Verkaufsformular aktualisieren */
netProfit = Math.round(netProfit * 100) / 100;
replaceText(netProfitEl, netProfit);
Listing
1 ist ziemlich einfach; Listing 4 ist etwas komplizierter, aber beide überprüfen zu Beginn den Bereitschaftsstatus und erhalten den Wert der ResponseText-Eigenschaft.
Den Antworttext einer Anfrage anzeigen
Ähnlich wie der Bereitschaftsstatus ändert sich auch der Wert der Eigenschaft „responseText“ während der Lebensdauer der Anfrage. Um diese Änderung zu sehen, verwenden Sie den in Listing 5 gezeigten Code, um den Antworttext der Anfrage sowie deren Bereitschaftsstatus zu testen.
Listing 5. Testen der Eigenschaftsfunktion „responseText“
updatePage() {
// Den aktuellen Bereitschaftszustand ausgeben
alarm("updatePage() wird mit dem Bereitschaftsstatus " + request.readyState + aufgerufen
" und ein Antworttext von '" + request.responseText + "'");
}
Öffnen Sie nun die Webanwendung in Ihrem Browser und aktivieren Sie Ihre Anfrage. Um die Wirkung dieses Codes besser zu sehen, verwenden Sie Firefox oder Internet Explorer, da beide Browser während der Anfrage alle möglichen Bereitschaftszustände melden können. Beispielsweise ist im Bereitschaftszustand 2 „responseText“ nicht definiert (siehe Abbildung 3); wenn die JavaScript-Konsole ebenfalls geöffnet ist, wird eine Fehlermeldung angezeigt.
Abbildung 3. Antworttext für den Bereitschaftsstatus 2
Allerdings hat der Server im Bereitschaftszustand 3 zumindest in diesem Beispiel einen Wert in die Eigenschaft „responseText“ eingefügt (siehe Abbildung 4).
Abbildung 4. Antworttext für den Bereitschaftsstatus 3
Sie werden sehen, dass die Antwort mit einem Bereitschaftsstatus von 3 in jedem Skript, jedem Server und sogar jedem Browser unterschiedlich ist. Dies ist jedoch beim Debuggen von Anwendungen immer noch sehr nützlich.
Sichere Datengewinnung
Alle Dokumente und Spezifikationen betonen, dass Daten nur dann sicher genutzt werden können, wenn der Bereitschaftsstatus 4 ist. Glauben Sie mir, wenn der Bereitschaftsstatus 3 ist, werden Sie selten eine Situation finden, in der Sie keine Daten aus der Eigenschaft „responseText“ abrufen können. Es ist jedoch keine gute Idee, Ihre eigene Logik in Ihrer Anwendung vom Bereitschaftszustand 3 abhängig zu machen – sobald Sie Code schreiben, der auf vollständigen Daten im Bereitschaftszustand 3 basiert, sind Sie zu diesem Zeitpunkt fast für die unvollständigen Daten verantwortlich.
Ein besserer Ansatz besteht darin, dem Benutzer eine Rückmeldung zu geben, dass die Reaktion im Bereitschaftszustand 3 bald erfolgen wird. Obwohl die Verwendung von Funktionen wie „alert()“ offensichtlich eine schlechte Idee ist – die Verwendung von Ajax und das anschließende Blockieren des Benutzers mit einem Warndialogfeld ist offensichtlich falsch –, können Sie Felder in einem Formular oder einer Seite aktualisieren, wenn sich der Bereitschaftsstatus ändert. Legen Sie beispielsweise für den Bereitschaftszustand 1 die Breite der Fortschrittsanzeige auf 25 % fest, für den Bereitschaftszustand 2 die Breite der Fortschrittsanzeige auf 50 % und für den Bereitschaftszustand 3 die Breite der Fortschrittsanzeige auf 25 % % Die Breite ist auf 75 % eingestellt, und wenn der Bereitschaftsstatus 4 ist, wird die Breite der Fortschrittsanzeige auf 100 % (abgeschlossen) gesetzt.
Natürlich ist diese Methode, wie Sie bereits gesehen haben, sehr clever, aber sie ist browserabhängig. In Opera sehen Sie nie die ersten beiden Bereitschaftszustände und in Safari gibt es keinen ersten (1). Aus diesem Grund habe ich diesen Code als Übung belassen und ihn nicht in diesen Artikel aufgenommen.
Jetzt ist es an der Zeit, sich die Statuscodes anzusehen.
Ein tieferer Blick auf HTTP-Statuscodes
Mit dem Bereitschaftsstatus und der Serverantwort, die Sie in Ajax-Programmiertechniken gelernt haben, können Sie Ihren Ajax-Anwendungen eine weitere Ebene der Komplexität hinzufügen – mithilfe von HTTP-Statuscodes. In diesem Code gibt es nichts Neues über Ajax. Sie gibt es seit den Anfängen des Webs. Möglicherweise haben Sie in Webbrowsern mehrere Statuscodes gesehen:
· 401: Nicht autorisiert · 403: Verboten · 404: Nicht gefunden
Weitere Statuscodes finden Sie (eine vollständige Liste finden Sie unter Ressourcen). Um Ihren Ajax-Anwendungen eine zusätzliche Ebene von Kontroll- und Antwortmechanismen (und robusteren Fehlerbehandlungsmechanismen) hinzuzufügen, müssen Sie Statuscodes in Anforderungen und Antworten ordnungsgemäß anzeigen.
200: Alles ist in Ordnung.
In vielen Ajax-Anwendungen sehen Sie eine Callback-Funktion, die dafür verantwortlich ist, den Bereitschaftsstatus zu überprüfen und dann die von der Serverantwort zurückgegebenen Daten weiter zu verwenden, wie in Listing 6 gezeigt.
Listing 6. Rückruffunktion, die die Statuscodefunktion
updatePage() {
ignoriert
if (request.readyState == 4) {
var Response = request.responseText.split("|");
document.getElementById("order").value = Response[0];
document.getElementById("address").innerHTML =
Antwort[1].replace(/n/g, "<br />");
}
}
Dies stellt sich als kurzsichtiger und falscher Ansatz zur Ajax-Programmierung heraus. Wenn das Skript eine Authentifizierung erfordert und die Anfrage kein gültiges Zertifikat bereitstellt, gibt der Server einen Fehlercode wie 403 oder 401 zurück. Da der Server jedoch auf die Anfrage geantwortet hat, wird der Bereitschaftsstatus auf 4 gesetzt (auch wenn die Antwort nicht den Erwartungen der Anfrage entsprach). Letztendlich erhält der Benutzer keine gültigen Daten und es können schwerwiegende Fehler auftreten, wenn JavaScript versucht, nicht vorhandene Serverdaten zu verwenden.
Mit minimalem Aufwand kann sichergestellt werden, dass der Server nicht nur eine Anfrage abschließt, sondern auch einen „Alles in Ordnung“-Statuscode zurückgibt. Dieser Code ist „200“, der über das Statusattribut des XMLHttpRequest-Objekts gemeldet wird. Um sicherzustellen, dass der Server nicht nur eine Anfrage abgeschlossen, sondern auch einen OK-Status gemeldet hat, fügen Sie Ihrer Rückruffunktion eine weitere Prüfung hinzu, wie in Listing 7 gezeigt.
Listing 7.Funktion updatePage() {
auf gültige Statuscodes prüfen
if (request.readyState == 4) {
if (request.status == 200) {
var Response = request.responseText.split("|");
document.getElementById("order").value = Response[0];
document.getElementById("address").innerHTML =
Antwort[1].replace(/n/g, "<br />");
} anders
Alert("Status ist " + request.status);
}
}
Durch das Hinzufügen dieser wenigen Codezeilen können Sie bestätigen, ob ein Problem vorliegt, und dem Benutzer wird eine hilfreiche Fehlermeldung angezeigt, anstatt nur eine Seite mit aus dem Kontext gerissenen Daten ohne Erklärung zu sehen.
Weiterleitungen und Umleitungen
Bevor wir uns mit den Details zu Fehlern befassen, lohnt es sich, ein Problem zu besprechen, über das Sie sich bei der Verwendung von Ajax keine Sorgen machen müssen – Weiterleitungen. Unter den HTTP-Statuscodes ist dies die 300er-Reihe von Statuscodes, einschließlich:
301: Permanent verschoben 302: Gefunden (Anfrage an eine andere URL/URI umgeleitet)
·305: Verwendung eines Proxys (die Anfrage muss einen Proxy verwenden, um auf die angeforderte Ressource zuzugreifen)
Ajax-Programmierer machen sich aus zwei Gründen möglicherweise keine allzu großen Sorgen über Umleitungsprobleme:
·Erstens sind Ajax-Anwendungen normalerweise für eine bestimmte Serverseite geschrieben Skript, Servlet oder Anwendung. Ajax-Programmierer sind sich weniger im Klaren über Komponenten, die verschwinden, ohne dass Sie sie sehen. Manchmal wissen Sie also, dass die Ressource verschoben wurde (weil Sie sie verschoben haben oder auf irgendeine Weise verschoben haben), und ändern dann die URL in der Anfrage und stoßen nie wieder auf dieses Ergebnis.
Ein wichtigerer Grund ist, dass Ajax-Anwendungen und -Anfragen in einer Sandbox gekapselt sind. Das bedeutet, dass die Domäne, die die Webseiten bedient, die Ajax-Anfragen generieren, die Domäne sein muss, die auf diese Anfragen antwortet. Daher kann die von ebay.com bereitgestellte Webseite keine Ajax-Anfrage an ein Skript stellen, das auf amazon.com ausgeführt wird. Eine Ajax-Anwendung auf ibm.com kann keine Anfrage an Servlets stellen, die auf netbeans.org ausgeführt werden.
·Das Ergebnis ist, dass Ihre Anfrage nicht an einen anderen Server umgeleitet werden kann, ohne dass ein Sicherheitsfehler auftritt. In diesen Fällen erhalten Sie überhaupt keinen Statuscode. Normalerweise wird in der Debug-Konsole ein JavaScript-Fehler generiert. Daher können Sie das Problem der Weiterleitungscodes völlig ignorieren, nachdem Sie sich ausreichend Gedanken über Statuscodes gemacht haben.
Dies führt dazu, dass Ihre Anfrage nicht an einen anderen Server umgeleitet werden kann, ohne dass ein Sicherheitsfehler auftritt. In diesen Fällen erhalten Sie überhaupt keinen Statuscode. Normalerweise wird in der Debug-Konsole ein JavaScript-Fehler generiert. Daher können Sie das Problem der Weiterleitungscodes völlig ignorieren, nachdem Sie sich ausreichend Gedanken über Statuscodes gemacht haben.
Fehler
Sobald Sie den Statuscode 200 erhalten und feststellen, dass Sie die Statuscodes der 300er-Serie weitgehend ignorieren können, müssen Sie sich nur noch um die Codes der 400er-Serie kümmern, die die verschiedenen Arten von Fehlern veranschaulichen. Schauen Sie sich Listing 7 noch einmal an und stellen Sie fest, dass beim Umgang mit Fehlern nur wenige häufige Fehlermeldungen an den Benutzer ausgegeben werden. Obwohl dies ein Schritt in die richtige Richtung ist, sind diese Meldungen immer noch nicht sehr nützlich, um Benutzern und Programmierern, die an der Anwendung arbeiten, mitzuteilen, was genau schief läuft.
Zunächst fügen wir Unterstützung für nicht gefundene Seiten hinzu. Dies sollte in den meisten Produktionssystemen eigentlich nicht passieren, es kommt jedoch nicht selten vor, dass sich der Speicherort des Testskripts ändert oder der Programmierer die falsche URL eingibt. Wenn Sie 404-Fehler auf natürliche Weise melden können, können Sie frustrierten Benutzern und Programmierern mehr Hilfe bieten. Wenn beispielsweise ein Skript auf dem Server gelöscht wird, können wir den Code in Listing 7 verwenden, sodass der Benutzer einen nicht beschreibenden Fehler wie den in Abbildung 5 gezeigten sieht.
Grenzfälle und schwierige Situationen
An dieser Stelle fragen sich einige unerfahrene Programmierer möglicherweise, worum es geht. Hier ist eine Tatsache, die Sie wissen müssen: Weniger als 5 % der Ajax-Anfragen verwenden Bereitschaftszustände wie 2 und 3 und Statuscodes wie 403 (tatsächlich liegt diese Rate wahrscheinlich eher bei 1 % oder sogar weniger). Diese Situationen sind sehr wichtig und werden Randfälle genannt – sie treten nur in ganz bestimmten Situationen auf, in denen die exotischsten Probleme auftreten. Obwohl diese Situationen nicht häufig vorkommen, sind diese Grenzfälle für 80 % der Probleme verantwortlich, mit denen die meisten Benutzer konfrontiert sind.
Der typische Benutzer vergisst normalerweise die Tatsache, dass die Anwendung 100 Mal korrekt funktioniert. Ein Fehler in der Anwendung bleibt jedoch deutlich im Gedächtnis ihnen. Wenn Sie Randfälle (oder schwierige Situationen) gut bewältigen können, können Sie den Benutzern, die auf Ihre Website zurückkehren, zufriedenstellende Belohnungen bieten.
Abbildung 5. Häufige Fehlerbehandlung
Der Benutzer kann nicht erkennen, ob es sich bei dem Problem um ein Authentifizierungsproblem, ein nicht gefundenes Skript (wie hier), einen Benutzerfehler oder etwas anderes im Code handelt. Durch Hinzufügen von einfachem Code kann dieser Fehler spezifischer gemacht werden. Bitte beachten Sie Listing 8, das für die Behandlung von Situationen verantwortlich ist, in denen das Skript nicht gefunden wird oder ein Authentifizierungsfehler auftritt. Wenn diese Fehler auftreten, werden bestimmte Meldungen angezeigt.
Listing 8.Funktion updatePage() {
auf gültige Statuscodes prüfen
if (request.readyState == 4) {
if (request.status == 200) {
var Response = request.responseText.split("|");
document.getElementById("order").value = Response[0];
document.getElementById("address").innerHTML =
Antwort[1].replace(/n/g, "<br />");
} else if (request.status == 404) {
Warnung („Angeforderte URL wurde nicht gefunden.“);
} else if (request.status == 403) {
Alert("Zugriff verweigert.");
} anders
Alert("Status ist " + request.status);
}
}
Obwohl dies immer noch recht einfach ist, bietet es einige nützlichere Informationen. Abbildung 6 zeigt den gleichen Fehler wie Abbildung 5, aber dieses Mal erklärt der Fehlerbehandlungscode dem Benutzer oder Programmierer besser, was genau passiert ist.
Abbildung 6. Spezielle Fehlerbehandlung
In unserer eigenen Anwendung könnten wir erwägen, den Benutzernamen und das Passwort zu löschen und im Falle eines Authentifizierungsfehlers eine Fehlermeldung auf dem Bildschirm hinzuzufügen. Wir können einen ähnlichen Ansatz verwenden, um besser mit nicht gefundenen Skripten oder anderen Fehlern vom Typ 400 umzugehen (405 bedeutet beispielsweise, dass eine inakzeptable Anforderungsmethode wie das Senden einer HEAD-Anfrage nicht zulässig ist, und 407 bedeutet, dass eine Proxy-Authentifizierung erforderlich ist). Unabhängig davon, für welche Option Sie sich entscheiden, müssen Sie jedoch mit der Verarbeitung des vom Server zurückgegebenen Statuscodes beginnen.
Andere Anforderungstypen
Wenn Sie wirklich die Kontrolle über das XMLHttpRequest-Objekt haben möchten, sollten Sie erwägen, diese letzte Funktionalität zu implementieren, indem Sie der Direktive die HEAD-Anfrage hinzufügen. In den beiden vorherigen Artikeln haben wir vorgestellt, wie man GET-Anfragen generiert. In einem kommenden Artikel erfahren Sie, wie Sie POST-Anfragen zum Senden von Daten an den Server verwenden. Im Sinne einer verbesserten Fehlerbehandlung und Informationserfassung sollten Sie jedoch lernen, wie Sie HEAD-Anfragen generieren.
Die Anfrage stellen
Die HEAD-Anfrage zu stellen ist eigentlich sehr einfach; Sie rufen die open()-Methode mit „HEAD“ (anstelle von „GET“ oder „POST“) als erstem Parameter auf, wie in Listing 9 gezeigt.
Listing 9. Verwenden von Ajax zum Generieren einer HEAD-Anfragefunktion
getSalesData() {
createRequest();
var url = "/boards/servlet/UpdateBoardSales";
request.open("HEAD", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
Wenn Sie eine solche HEAD-Anfrage generieren, gibt der Server keine echte Antwort zurück, wie dies bei einer GET- oder POST-Anfrage der Fall wäre. Stattdessen gibt der Server nur den Header der Ressource zurück, der enthält, wann der Inhalt der Antwort zuletzt geändert wurde, ob die angeforderte Ressource existiert und viele andere nützliche Informationen. Mithilfe dieser Informationen können Sie mehr über die Ressource erfahren, bevor sie vom Server verarbeitet und zurückgegeben wird.
Das einfachste, was Sie für diese Art von Anfrage tun können, besteht darin, einfach den Inhalt aller Antwortheader auszugeben. Dadurch erhalten Sie eine Vorstellung davon, was über die HEAD-Anfrage verfügbar ist. Listing 10 stellt eine einfache Rückruffunktion bereit, die den Inhalt des Antwortheaders ausgibt, der von der HEAD-Anfrage erhalten wurde.
Listing 10. Geben Sie den Inhalt des Antwortheaders aus, der von der HEAD-Anforderungsfunktion
updatePage() erhalten wurde.
if (request.readyState == 4) {
alarm(request.getAllResponseHeaders());
}
}
Siehe Abbildung 7, die die Antwortheader zeigt, die von einer einfachen Ajax-Anwendung zurückgegeben werden, die eine HEAD-Anfrage an den Server stellt.
Sie können diese Header einzeln (vom Servertyp bis zum Inhaltstyp) verwenden, um zusätzliche Informationen oder Funktionen in Ihrer Ajax-Anwendung bereitzustellen.
Überprüfen der URL
Sie haben gesehen, wie Sie nach 404-Fehlern suchen, wenn die URL nicht vorhanden ist. Wenn sich herausstellt, dass dies ein häufiges Problem ist – vielleicht fehlt ein bestimmtes Skript oder Servlet –, sollten Sie die URL überprüfen, bevor Sie eine vollständige GET- oder POST-Anfrage stellen. Um diese Funktionalität zu implementieren, generieren Sie eine HEAD-Anfrage und prüfen Sie dann die Rückruffunktion auf 404-Fehler. Listing 11 zeigt eine einfache Rückruffunktion.
Listing 11. Überprüfen, ob eine URL vorhanden ist,
Funktion updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
alarm("URL existiert");
} else if (request.status == 404) {
alarm("URL existiert nicht.");
} anders {
Alert("Status ist: " + request.status);
}
}
}
Ehrlich gesagt ist der Wert dieses Codes nicht so groß. Der Server muss auf die Anfrage antworten und eine Antwort erstellen, um den Content-Length-Antwortheader aufzufüllen, damit keine Verarbeitungszeit gespart wird. Darüber hinaus nimmt dies genauso viel Zeit in Anspruch wie das Generieren der Anfrage und die Verwendung einer HEAD-Anfrage, um zu sehen, ob die URL existiert, da die Anfrage mit GET oder POST generiert wird und nicht nur der Fehlercode verarbeitet wird, wie in Listing 7 gezeigt. Manchmal ist es jedoch hilfreich, genau zu wissen, was derzeit verfügbar ist; man weiß nie, wann Ihre Kreativität einsetzen wird oder wann Sie eine HEAD-Anfrage benötigen!
Nützliche HEAD-Anfragen
Ein Bereich, in dem Sie die HEAD-Anfrage möglicherweise sehr nützlich finden, ist die Anzeige der Länge des Inhalts oder der Art des Inhalts. Dadurch kann festgestellt werden, ob eine große Datenmenge zurückgesendet werden muss, um die Anfrage zu verarbeiten, und ob der Server versucht, Binärdaten anstelle von HTML, Text oder XML zurückzugeben (alle drei Datentypen sind in JavaScript einfacher zu verarbeiten als binäre Daten).
In diesen Fällen verwenden Sie einfach den entsprechenden Headernamen und übergeben ihn an die getResponseHeader()-Methode des XMLHttpRequest-Objekts. Um die Länge der Antwort zu erhalten, rufen Sie einfach request.getResponseHeader("Content-Length"); auf. Um den Inhaltstyp abzurufen, verwenden Sie request.getResponseHeader("Content-Type");.
In vielen Anwendungen bringt das Generieren einer HEAD-Anfrage keine zusätzliche Funktionalität mit sich und kann sogar dazu führen, dass die Anfrage langsamer ist (indem eine HEAD-Anfrage gezwungen wird, Daten über die Antwort abzurufen, und dann eine GET- oder POST-Anfrage verwendet wird, um die Antwort tatsächlich abzurufen). In Situationen, in denen Sie sich über ein Skript oder eine serverseitige Komponente nicht sicher sind, können Sie mithilfe einer HEAD-Anfrage einige grundlegende Daten abrufen, ohne die Antwortdaten tatsächlich zu verarbeiten oder viel Bandbreite zum Senden der Antwort zu benötigen.
Fazit
Für viele Ajax- und Web-Programmierer scheint das in diesem Artikel vorgestellte Material zu fortgeschritten zu sein. Welchen Wert hat die Generierung einer HEAD-Anfrage? Wann müssen Sie Weiterleitungsstatuscodes in JavaScript explizit verarbeiten? Das sind gute Fragen; für einfache Anwendungen lautet die Antwort, dass der Wert dieser fortgeschrittenen Techniken nicht sehr groß ist.
Allerdings ist das Web nicht länger ein Ort, an dem man nur einfache Anwendungen implementieren muss; die Benutzer sind fortgeschrittener geworden, Kunden erwarten eine bessere Stabilität, eine erweiterte Fehlerberichterstattung, und wenn eine Anwendung in 1 % der Fälle ausfällt, dann könnte das der Manager sein dafür gefeuert werden.
Daher kann sich Ihre Arbeit nicht auf einfache Anwendungen beschränken, sondern erfordert ein tieferes Verständnis von XMLHttpRequest.
·Wenn Sie über verschiedene Bereitschaftszustände nachdenken und verstehen, wie sich diese Bereitschaftszustände zwischen den Browsern unterscheiden, können Sie Ihre Anwendung schnell debuggen. Sie können sogar einige kreative Funktionen basierend auf dem Bereitschaftsstatus entwickeln und den angeforderten Status an Benutzer und Kunden zurückmelden.
·Wenn Sie Statuscodes steuern möchten, können Sie Ihre Anwendung so einrichten, dass sie Skriptfehler, unerwartete Antworten und Grenzfälle verarbeitet. Das Ergebnis ist eine Anwendung, die jederzeit korrekt funktioniert, nicht nur, wenn alles in Ordnung ist.
· Fügen Sie die Möglichkeit hinzu, HEAD-Anfragen zu generieren, zu überprüfen, ob eine URL vorhanden ist, und zu bestätigen, ob eine Datei geändert wurde, um sicherzustellen, dass Benutzer gültige Seiten erhalten und dass die Informationen, die Benutzer sehen, die neuesten sind (was am wichtigsten ist), sie überraschen wie robust und vielseitig diese App ist.
Der Zweck dieses Artikels besteht nicht darin, Ihre Anwendung schick aussehen zu lassen, sondern Ihnen dabei zu helfen, das gelbe Rampenlicht zu entfernen und die Schönheit des Textes hervorzuheben oder eher wie einen Desktop auszusehen. Obwohl dies alles Funktionen von Ajax sind (die in den nächsten Artikeln behandelt werden), sind sie wie eine Schicht Sahne auf dem Kuchen. Wenn Sie mit Ajax eine solide Grundlage schaffen können, damit Ihre Anwendung gut mit Fehlern und Problemen umgehen kann, kehren Benutzer zu Ihrer Website und Anwendung zurück. Im nächsten Artikel werden wir diese intuitive Technik hinzufügen, die Ihre Kunden vor Aufregung zittern lässt. (Im Ernst, Sie möchten den nächsten Artikel nicht verpassen!)