Wie kann ich jQuery dazu bringen, eine synchrone, nicht asynchrone Ajax-Anforderung auszuführen?

Ich habe ein Javascript-Widget, das Standarderweiterungspunkte enthält. Eine davon ist die Funktion vor dem beforecreate . Es muss false , um zu verhindern, dass das Element erstellt wird.

Ich habe dieser Funktion einen Ajax-Aufruf mit jQuery hinzugefügt:

 beforecreate: function (node, targetNode, type, to) { jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value), function (result) { if (result.isOk == false) alert(result.message); }); } 

Ich möchte jedoch, dass mein Widget dieses Element nicht erstellt. Daher muss ich false in der mother-Funktion und nicht im Callback zurückgeben. Gibt es eine Möglichkeit, eine synchrone AJAX-Anforderung mithilfe von jQuery oder einer anderen API im Browser auszuführen?

1079
25 сент. eingestellt von Artem Tikhomirov 25 Sep. 2008-09-25 16:26 08 um 16:26 Uhr 2008-09-25 16:26
@ 14 Antworten

Aus der jQuery-Dokumentation : Sie geben die asynchrone Option auf false an, um eine synchrone Ajax-Anforderung zu erhalten. Ihr Callback kann dann einige Daten festlegen, bevor Ihre übergeordnete Funktion fortgesetzt wird.

So würde Ihr Code aussehen, wenn er wie vorgeschlagen geändert wurde:

 beforecreate: function (node, targetNode, type, to) { jQuery.ajax({ url: 'http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value), success: function (result) { if (result.isOk == false) alert(result.message); }, async: false }); } 
1053
25 сент. Die Antwort gibt Adam Bellaire 25 Sep. 2008-09-25 16:30 08 um 16:30 Uhr 2008-09-25 16:30 Uhr

Sie können jQuery Ajax im synchronen Modus installieren, indem Sie es aufrufen

 jQuery.ajaxSetup({async:false}); 

jQuery.get(... ); dann Ihre Ajax-Aufrufe mit jQuery.get(... );

border=0

Dann einfach wieder einschalten.

 jQuery.ajaxSetup({async:true}); 

Ich gehe davon aus, dass dies auf dieselbe Weise funktioniert wie von @Adam vorgeschlagen, aber es kann für jemanden nützlich sein, der jQuery.get() oder jQuery.post() in die komplexere jQuery.ajax() jQuery.post() umkonfigurieren möchte.

239
13 апр. Antwort von Sydwell am 13. April 2011-04-13 00:45 '11 am 0:45 2011-04-13 00:45

Tolle Lösung! Ich bemerkte, dass, als ich versuchte, es zu implementieren, den Wert als zurückgegeben an die Erfolgsklausel zurückgab und er als undefiniert zurückgegeben wurde. Ich musste es in einer Variablen speichern und diese Variable zurückgeben. Dies ist die Methode, die ich mir ausgedacht habe:

 function getWhatever() { // strUrl is whatever URL you need to call var strUrl = "", strReturn = ""; jQuery.ajax({ url: strUrl, success: function(html) { strReturn = html; }, async:false }); return strReturn; } 
128
07 апр. Antwort von James in Indy 07 Apr 2010-04-07 16:30 '10 um 16:30 2010-04-07 16:30

All diese Antworten stimmen nicht darin überein, dass der Browser bei einem Ajax-Anruf mit async: false hängen bleibt, bis die Ajax-Anforderung abgeschlossen ist. Die Verwendung der Flusssteuerungsbibliothek löst dieses Problem, ohne dass der Browser hängen bleibt. Unten ist ein Beispiel mit Frame.js :

 beforecreate: function(node,targetNode,type,to) { Frame(function(next)){ jQuery.get('http://example.com/catalog/create/', next); }); Frame(function(next, response)){ alert(response); next(); }); Frame.init(); } 
82
28 апр. Die Antwort wird BishopZ 28 April gegeben. 2012-04-28 20:41 '12 um 20:41 Uhr 2012-04-28 20:41
 function getURL(url){ return $.ajax({ type: "GET", url: url, cache: false, async: false }).responseText; } //example use var msg=getURL("message.php"); alert(msg); 
49
25 апр. Die Antwort gibt Carcione am 25. April. 2012-04-25 18:34 '12 am 18:34 2012-04-25 18:34

Denken Sie daran, dass, wenn Sie einen Ajax-Crossdomain-Aufruf (mithilfe von JSONP ) ausführen, dies nicht synchron erfolgen kann, das async Flag von jQuery ignoriert wird.

 $.ajax({ url: "testserver.php", dataType: 'jsonp', // jsonp async: false //IGNORED!! }); 

Für JSONP-Aufrufe können Sie Folgendes verwenden:

  • Ajax-Anruf an Ihre eigene Domäne - und serverseitig einen domänenübergreifenden Anruf tätigen
  • Ändern Sie Ihren Code so, dass er asynchron arbeitet.
  • Verwenden Sie die Sequenzer-Funktionsbibliothek, z. B. Frame.js (diese Antwort ).
  • Blockieren Sie die Benutzeroberfläche, anstatt die Ausführung zu blockieren (diese Antwort ) (mein bevorzugter Weg)
22
10 мая '15 в 9:28 2015-05-10 09:28 Die Antwort wird von Serge Shultz am 10. Mai 15 um 09:28 2015-05-10 09:28 gegeben

Hinweis Sie sollten aus diesem Grund nicht async verwenden:

Ab Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27) sind die synchronen Anforderungen im Haupt-Thread aufgrund der negativen Folgen für den Benutzer veraltet.

Chrome warnt sogar in der Konsole darüber:

Synchrones XMLHttpRequest im Haupt-Thread ist aufgrund seiner nachteiligen Auswirkungen auf den Endbenutzer veraltet. Weitere Informationen finden Sie unter https://xhr.spec.whatwg.org/ .

Wenn Sie so etwas tun, kann Ihre Seite beschädigt werden, da sie jeden Tag nicht mehr funktioniert.

Wenn Sie es so tun wollen, als ob es synchron ist, aber nicht blockiert, sollten Sie async / wait und möglicherweise auch ajax verwenden, basierend auf Versprechungen wie dem neuen API- Fetch

 async function foo() { var res = await fetch(url) console.log(res.ok) var json = await res.json() console.log(json) } 
19
13 дек. Die Antwort ist Endless 13. Dezember gegeben. 2016-12-13 15:55 '16 am 15:55 2016-12-13 15:55

Ich habe die Antwort von Carcione verwendet und sie in JSON geändert.

  function getUrlJsonSync(url){ var jqxhr = $.ajax({ type: "GET", url: url, dataType: 'json', cache: false, async: false }); // 'async' has to be 'false' for this to work var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON}; return response; } function testGetUrlJsonSync() { var reply = getUrlJsonSync("myurl"); if (reply.valid == 'OK') { console.dir(reply.data); } else { alert('not valid'); } } 

Ich habe den Datentyp 'JSON' hinzugefügt und den .responseText in responseJSON geändert.

Ich habe auch den Status mit der Eigenschaft statusText des zurückgegebenen Objekts erhalten. Bitte beachten Sie, dass dies ein Ajax-Antwortstatus ist und kein gültiger JSON-Code.

Der interne Server muss die Antwort in der korrekten (wohlgeformten) JSON zurückgeben, andernfalls ist das zurückgegebene Objekt undefiniert.

Bei der Beantwortung der ursprünglichen Frage sind zwei Aspekte zu berücksichtigen. Einer sagt Ajax, dass es synchron ausgeführt werden soll (indem es async: false setzt ), und der andere gibt die Antwort über den Callback-Return-Operator zurück und nicht an die Callback-Funktion.

Ich habe es auch mit POST ausprobiert und es hat funktioniert.

Ich habe GET in POST geändert und Daten hinzugefügt : Postdata

 function postUrlJsonSync(url, postdata){ var jqxhr = $.ajax({ type: "POST", url: url, data: postdata, dataType: 'json', cache: false, async: false }); // 'async' has to be 'false' for this to work var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON}; return response; } 

Bitte beachten Sie, dass der obige Code nur funktioniert, wenn async falsch ist . Wenn Sie async: true festlegen mussten , ist das zurückgegebene jqxhr- Objekt während eines AJAX-Aufrufs erst später ungültig, wenn der asynchrone Aufruf abgeschlossen ist. Es ist jedoch zu spät, um die Antwortvariable festzulegen.

10
15 нояб. antwort gegeben paulo62 15 nov. 2014-11-15 14:33 '14 am 14:33 2014-11-15 14:33

Mit async: false Sie einen blockierten Browser. Für eine nicht blockierende, synchrone Lösung können Sie Folgendes verwenden:

ES6 / ECMAScript2015

Mit ES6 können Sie die Generator- und Co-Bibliothek verwenden :

 beforecreate: function (node, targetNode, type, to) { co(function*(){ let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value)); //Just use the result here }); } 

ES7

Mit ES7 können Sie einfach asyc wait verwenden:

 beforecreate: function (node, targetNode, type, to) { (async function(){ let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value)); //Just use the result here })(); } 
9
20 авг. Die Antwort ist Spen 20 Aug gegeben. 2016-08-20 22:52 '16 um 22:52 Uhr 2016-08-20 22:52

Dies ist ein Beispiel:

 $.ajax({ url: "test.html", async: false }).done(function(data) { // Todo something.. }).fail(function(xhr) { // Todo something.. }); 
6
16 авг. antwort gegeben suche 9x 16 aug. 2014-08-16 16:20 14 um 16:20 2014-08-16 16:20

JavaScript-Clientcode in Javascript

 function isValidLogin() { var flag = false; var Response = $.ajax({ type: "POST", dataType: "json", contentType: "application/json; charset=utf-8", url: "UPSLabelFormCA.aspx/IsValidLogin", async: false }).responseText; var toJson = jQuery.parseJSON(Response); if (toJson.d[0].Message == 'SUCCESS') { flag = true; } return flag; } 

ASP.NET-Servercode

 [WebMethod] public static List<ShipInfo> IsValidLogin() { List<ShipInfo> loginStatus = new List<ShipInfo>(); if (HttpContext.Current.User.Identity.IsAuthenticated  HttpContext.Current.Session["Email"] != null) { loginStatus.Add(new ShipInfo() { Success = true, Message = "SUCCESS" }); } else { loginStatus.Add(new ShipInfo() { Success = false, Message = "FAILED" }); } return loginStatus; } 
5
02 дек. Antwort an Thomas 02 Dez 2014-12-02 16:02 14 um 16:02 2014-12-02 16:02

Zuerst müssen wir verstehen, wann wir $ .ajax und $ .get / $ verwenden. post

Wenn eine geringe Kontrolle über die Ajax-Anforderung erforderlich ist, z. B. Anforderungsheader-Einstellungen, Cache-Einstellungen, synchrone Einstellungen usw., müssen wir uns für $ .ajax entscheiden.

$. bekomme / $. post: Wenn wir keine Low-Level-Kontrolle über die Ajax-Anforderung benötigen. Empfangen und senden Sie einfach Daten an den Server. Diese Abkürzung

 $.ajax({ url: url, data: data, success: success, dataType: dataType }); 

Daher können wir keine anderen Funktionen (Synchronisation, Cache usw.) verwenden, die $ .get / $ verwenden. post.

Um niedrige Ebenen (Synchronisierung, Cache usw.) auf ajax-Anforderung zu verwalten, müssen wir daher zu $ ​​.ajax wechseln

  $.ajax({ type: 'GET', url: url, data: data, success: success, dataType: dataType, async:false }); 
2
03 окт. Antwort von Sheo Dayal Singh 03 Okt 2017-10-03 12:52 '17 am 12:52 2017-10-03 12:52

Dies ist meine einfache Implementierung für ASYNC-Abfragen mit jQuery. Hoffe, das hilft jedem.

 var queueUrlsForRemove = [ 'http://dev-myurl.com/image/1', 'http://dev-myurl.com/image/2', 'http://dev-myurl.com/image/3', ]; var queueImagesDelete = function(){ deleteImage( queueUrlsForRemove.splice(0,1), function(){ if (queueUrlsForRemove.length > 0) { queueImagesDelete(); } }); } var deleteImage = function(url, callback) { $.ajax({ url: url, method: 'DELETE' }).done(function(response){ typeof(callback) == 'function' ? callback(response) : null; }); } queueImagesDelete(); 
0
15 февр. Die Antwort gibt Felipe Marques am 15. Februar. 2018-02-15 22:55 18 um 22:55 Uhr 2018-02-15 22:55

Da die synchrone Operation XMLHttpReponse veraltet ist, habe ich die folgende Lösung gefunden, die XMLHttpRequest . Auf diese Weise können Sie AJAX-Anforderungen unter Beibehaltung einer asynchronen Art bestellen, was für einmalige CSRF-Token sehr nützlich ist.

Es ist auch transparent, so dass Bibliotheken wie jQuery ohne Probleme funktionieren.

  var XHRQueue = []; var _XMLHttpRequest = XMLHttpRequest; XMLHttpRequest = function() { var xhr = new _XMLHttpRequest(); var _send = xhr.send; xhr.send = function() {  XHRQueue.push([this, arguments]); if (XHRQueue.length == 1) this.processQueue(); }; xhr.processQueue = function() { var call = XHRQueue[0]; var xhr = call[0]; var args = call[1];   _send.apply(xhr, args); }; xhr.addEventListener('load', function(e) {   XHRQueue.shift(); if (XHRQueue.length) this.processQueue(); }); return xhr; }; 
0
29 апр. Geoffrey antwortete am 29. April 2018-04-29 13:50 '18 um 13:50 Uhr 2018-04-29 13:50 Uhr

Weitere Fragen zu Labels oder Eine Frage stellen