我怎样才能让jQuery执行同步而不是asynchronous的Ajax请求?

我有一个提供标准扩展点的JavaScript小部件。 其中之一是beforecreatefunction。 它应该返回false以防止创build项目。

我已经使用jQuery将Ajax调用添加到此函数中:

 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); }); } 

但是我想阻止我的小部件创build项目,所以我应该在母函数中返回false ,而不是在callback中。 有没有办法使用jQuery或任何其他API执行同步的Ajax请求?

从jQuery文档 :您指定asynchronous选项为false以获得同步Ajax请求。 然后,您的callback可以设置一些数据之前,你的母亲function进行。

如果按照build议进行更改,则代码如下所示:

 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 }); } 

您可以通过调用将jQuery的Ajax设置设置为同步模式

 jQuery.ajaxSetup({async:false}); 

然后使用jQuery.get( ... );执行Ajax调用jQuery.get( ... );

然后再打开一次

 jQuery.ajaxSetup({async:true}); 

我想它和@Adam的build议是一样的,但是对于那些想要将jQuery.get()jQuery.post()重新configuration成更复杂的jQuery.ajax()语法的人来说,这可能会有帮助。

优秀的解决 我注意到,当我试图实现它,如果我在成功的条款中返回一个值,它返回未定义。 我不得不把它存储在一个variables,并返回该variables。 这是我想出的方法:

 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; } 

所有这些答案都错过了使用async:false执行Ajax调用将导致浏览器挂起,直到Ajax请求完成。 使用stream量控制库将解决这个问题,而不会挂断浏览器。 这是一个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(); } 
 function getURL(url){ return $.ajax({ type: "GET", url: url, cache: false, async: false }).responseText; } //example use var msg=getURL("message.php"); alert(msg); 

请记住,如果您正在进行跨域Ajax调用(通过使用JSONP ) – 不能同步执行,则async标志将被jQuery忽略。

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

对于JSONP调用,您可以使用:

  1. Ajax调用你自己的域名 – 并进行跨域调用服务器端
  2. 改变你的代码asynchronous工作
  3. 使用“函数音序器”库像Frame.js(这个答案 )
  4. 阻止用户界面,而不是阻止执行(这个答案 )(我最喜欢的方式)

注意:你不应该使用async:

从Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)开始,由于对用户体验的负面影响,主线程上的同步请求已被弃用。

Chrome甚至在控制台中对此提出警告:

主线程上的同步XMLHttpRequest由于对最终用户的体验有不利的影响而被弃用。 如需更多帮助,请查看https://xhr.spec.whatwg.org/

这可能会打破你的网页,如果你正在做这样的事情,因为它可能会停止工作的任何一天。

如果你想这样做,仍然觉得,如果它是同步的,但仍然不阻止,那么你应该使用asynchronous/等待,也可能还有一些基于承诺的ajax,如新的Fetch API

 async function foo() { var res = await fetch(url) console.log(res.ok) var json = await res.json() console.log(json) } 

我使用了Carcione给出的答案,并将其修改为使用JSON。

  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'); } } 

我添加了“json”dataType并将.responseText更改为responseJSON

我也使用返回对象的statusText属性检索状态。 请注意,这是Ajax响应的状态,而不是JSON是否有效。

后端必须以正确的(格式良好的)JSON返回响应,否则返回的对象将是未定义的。

回答原来的问题时要考虑两个方面。 一个是告诉Ajax同步执行(通过设置async:false ),另一个通过调用函数的return语句返回响应,而不是callback函数。

我也试过用POST,它的工作。

我将GET更改为POST并添加了数据: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; } 

请注意,上述代码仅适用于asyncfalse的情况。 如果要设置async:true,那么返回的对象jqxhr在ajax调用返回时不会有效,只是在稍后asynchronous调用完成时才会生效,但是设置响应variables为时已晚。

async: false你让自己被阻止的浏览器。 对于非阻塞同步解决scheme,您可以使用以下方法:

ES6 / ECMAScript2015

有了ES6,你可以使用一个发生器和co库 :

 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

有了ES7,你可以使用asyc等待:

 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 })(); } 

这是例子:

 $.ajax({ url: "test.html", async: false }).done(function(data) { // Todo something.. }).fail(function(xhr) { // Todo something.. }); 

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服务器端代码

 [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; } 

首先,我们应该了解何时使用$ .ajax以及何时使用$ .get / $。post

当我们需要对ajax请求进行低级别的控制时,比如请求头部设置,caching设置,同步设置等。那么我们应该去$ .ajax。

$ .get / $。post:当我们不需要对ajax请求进行低级别的控制时,只需要简单地获取/发布数据到服务器。 这是速记

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

因此我们不能使用$ .get / $。post的其他function(同步,caching等)。

因此,对于ajax请求的低级控制(sync,cache等),我们应该去$ .ajax

  $.ajax({ type: 'GET', url: url, data: data, success: success, dataType: dataType, async:false });