Ajax-Anfrage mit JQuery auf Seite entladen

70

Ich versuche das zu tun:

$(window).unload( function () { 

$.ajax({
    type: "POST",
    url: "http://localhost:8888/test.php?",
    data: "test",
    success: function(msg){
         alert( "Data Saved: " + msg );
    }
}); 
alert (c);
});

Die Erfolgswarnung wird jedoch nie angezeigt, und diese Anforderung scheint auch nicht den Server zu treffen. Was mache ich falsch?

rauben
quelle

Antworten:

81

Ich glaube, Sie müssen die Anforderung stattdessen mithilfe des async : falseParameters synchronisieren (standardmäßig asynchron) .

Synchrone Anforderungen sperren den Browser, bis sie abgeschlossen sind. Wenn die Anforderung asynchron ist, wird die Seite einfach weiter entladen. Es ist schnell genug, dass die Anfrage nicht einmal Zeit zum Abfeuern hat.

Nate B.
quelle
Vielen Dank. Haben Sie eine Erklärung, warum dieser synchron sein muss?
Zigomir
2
Synchrone Anforderungen sperren den Browser, bis sie abgeschlossen sind. Wenn die Anforderung asynchron ist, wird die Seite einfach weiter entladen. Es ist schnell genug, dass die Anfrage nicht einmal Zeit zum Abfeuern hat.
Nate B
Bedeutet dies, dass die Anforderung manchmal gesendet werden kann, wenn das Entladen des Browsers besonders lange dauert (möglicherweise Probleme mit der Festplatte)? Oder wird es nie gesendet. Nur neugierig.
Farzher
11
Dies ist zwar die richtige Antwort, aber es ärgert mich, dass Sie nicht auch bemerkt haben, dass es böse ist . Bei langsamen Netzwerkverbindungen blockieren Sie die Browser der Benutzer, indem Sie die folgenden Schritte ausführen.
Mark Amery
Hat keinen Unterschied gemacht
user3953989
21

Versuchen Sie es mit async = false aufzurufen.

jQuery.ajax({url:"http://localhost:8888/test.php?", async:false})

Ich habe es gerade versucht.

Tebo
quelle
14

Die beste Lösung ist die Verwendung von navigator.sendBeacon . Es ist eine brandneue Funktionalität, die in neuen Versionen von Browsern implementiert wird. Die Funktion ist in Browsern verfügbar, die neuer als Chrome 39 und Firefox 31 sind. Sie wird zum Zeitpunkt des Schreibens von Internet Explorer und Safari nicht unterstützt. Um sicherzustellen, dass Ihre Anfrage in den Browsern gesendet wird, die die neue Funktionalität noch nicht unterstützen, können Sie folgende Lösung verwenden:

var navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
  var client = new XMLHttpRequest();
  client.open("POST", url, false); // third parameter indicates sync xhr
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(data);
};

Mit dieser Funktion können Sie jedoch keinen Onsuccess-Rückruf registrieren.

lswartsenburg
quelle
1
Derzeit ist dies immer noch als experimentell aufgeführt und "Syntax und Verhalten ... können sich in zukünftigen Versionen ändern"
Jeff Walker Code Ranger
UPDATE: Dies war möglicherweise nicht bekannt, als Sie diese Antwort geschrieben haben, aber sendBeacon sollte nicht mit den Ereignissen unloadund beforeunloadverwendet werden, da es möglicherweise nicht zuverlässig ausgelöst wird. Stattdessen sollte das visibilitychangeEreignis verwendet werden. Weitere Informationen finden Sie in den MDN-Dokumenten.
Henry Floyd
3

Die HTML - 5 - Spezifikation besagt , dass alert(), prompt()etc. werden nicht während der zur Verfügung window.unload()Veranstaltung. Weitere Informationen finden Sie unter window.unload () . Sie können das Ergebnis überprüfen, indem Sie console.log('success');anstelle von verwenden alert().

John Yeary
quelle
1

Vielleicht hätten Sie onbeforeunloadstattdessen mehr Erfolg mit der Veranstaltung?

   $(window).bind('beforeunload', ...
Scott Evernden
quelle
1
beforeunload-Ereignis wird von Safari
Sergey P. aka azure
0

Ihre Funktion und Ihr Ajax-Aufruf sehen gut aus. Ich vermute also, dass Ihr Browserfenster geschlossen ist, bevor der Ajax-Aufruf Zeit hat, zum Server und zurück zu gehen. Der Ajax-Aufruf gibt möglicherweise etwas zurück, wenn das Fenster geschlossen wird. Fügen Sie Ihrem Ajax-Aufruf eine Fehlerfunktion hinzu, um festzustellen, ob dies der Fall ist:

error: function (xhr, textStatus) {
    alert('Server error: '+ textStatus);
}
Marek Karbarz
quelle
1
Ich brauche es nicht wirklich, um "zurück" zu kommen (dh diese Warnung vor Erfolg ist nicht notwendig, sondern wird nur zu Debugging-Zwecken verwendet). Allerdings muss die Ajax-Anforderung ausgelöst werden, bevor das Entladen abgeschlossen ist.
Rob