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

我已经使用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);
  });
}

但是我想阻止小部件创建项目,所以我应该在母函数中返回false,而不是在回调中返回false。是否有一种方法可以使用jQuery或任何其他浏览器内API执行同步AJAX请求?


当前回答

我使用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”的数据类型,并将. responsetext更改为responseJSON。

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

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

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

我也尝试了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;
}

注意,上面的代码只在async为false的情况下有效。如果设置async: true,返回的对象jqxhr将在AJAX调用返回时无效,只有在异步调用结束后才有效,但此时设置响应变量已经太迟了。

其他回答

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

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

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

ajax—调用您自己的域—并在服务器端执行跨域调用 将代码更改为异步工作 使用像Frame.js这样的“函数排序器”库(这个答案) 阻塞UI而不是阻塞执行(这个答案)(我最喜欢的方式)

所有这些答案都忽略了一点,即使用async:false执行Ajax调用将导致浏览器挂起,直到Ajax请求完成。使用流控制库可以解决这个问题,而不需要挂起浏览器。下面是一个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);

首先,我们应该了解什么时候使用$。当我们使用$。get/$。post时

当我们需要对ajax请求进行低级控制时,例如请求头设置、缓存设置、同步设置等,那么我们应该使用$.ajax。

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

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

因此,我们不能在$.get/$.post中使用其他特性(同步,缓存等)。

因此,对于ajax请求的低级控制(同步,缓存等),我们应该使用$.ajax

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

因为最初的问题是关于jQuery的。在这里值得一提的是(正如这里提到的),可以在$.get()中使用async: false,但理想情况下要避免它,因为异步XMLHTTPRequest已弃用(浏览器可能会给出警告):

$.get({
  url: url,// mandatory
  data: data,
  success: success,
  dataType: dataType,
  async:false // to make it synchronous
});