jQuery.ajax成功回调函数未执行

32

我有一个JavaScript Ajax调用(jQuery.ajax),它没有执行成功回调函数。

$.ajax({
        url: target,
        contentType: 'application/json; charset=utf-8',
        type: 'POST',
        // type: 'GET',
        dataType: 'jsonp',
        error: function (xhr, status) {
            alert(status);
        },
        success: function (result) {
            alert("Callback done!");
            // grid.dataBind(result.results);
            // grid.dataBind(result);
        }
    });

我在Firebug中看到请求已经被提交,并且预期的JSON结果也已经返回了,但是出了什么问题?


3
我看到可能导致这种情况的一个问题是,托管页面和Ajax目标位于不同的域名下。 - artlung
这个可以尝试一下,我试过了,对我有用。 - Rupesh Terase
8个回答

61

我遇到过很多类似的问题,大多数情况下原因是json格式不正确。尝试将结果作为文本数据类型获取,以查看是否存在该问题。

此外,我想问一下,您是否在url中使用了类似于"&jsoncallback=?"的参数,因为您的数据类型是jsonp而不是简单的json。


9
我曾经有过类似的问题,大多是由于 JSON 格式错误造成的。请在 jsonlint.com 上验证您的 JSON 响应。 - Adeel
2
我验证了它是有效的JSON。 - Frank Michael Kraft

6

如果您的$.ajax调用中含有dataType: 'jsonp',那么它可以在以下情况下工作:

  1. 您正在调用与页面相同域的url。
  2. 您正在调用支持回调函数的页面之外的url。

如果不属于以上两种情况,则无法进行任何操作,因为您无法进行跨站点XmlHttpRequest调用。


实际上,你可以;至少在现代浏览器中可以。但我认为$.ajax不处理那个。 - Tgr
1
无论如何,如果这是一个跨站请求,AJAX调用首先就不会返回。 - Tgr
将脚本标签添加到页眉不是 AJAX 调用。(我不知道 jQuery 可以做到这一点,不过很酷。)在现代浏览器中,您可以进行实际的跨域 AJAX 调用。这将取决于目标服务器通过特殊的 HTTP 标头授权您,但他们通常不会这样做,因此目前实际应用有限。 - Tgr
我正在谈论OP所请求的Jquery的Ajax调用。 - systempuntoout
@Frank 你为什么要使用 dataType: 'jsonp'? - systempuntoout
显示剩余3条评论

3

这是一个老问题,但我怀疑人们仍然会遇到这个问题。

我曾经为此奋斗了一段时间,最终放弃并转向延迟模式。(我已经使用jQuery很长时间了,仍然保持着“旧”的习惯...)一旦我转向延迟模式,事情就开始运作了。我不知道为什么旧方法不起作用,但现在不再关心了。(这个问题出现在新模型之前。)

参考:https://dev59.com/6WUq5IYBdhLWcg3wJNBA#14754681


1

你需要将 async 属性设置为 false。

$.ajax({
    url: target,
    contentType: 'application/json; charset=utf-8',
    type: 'POST', // or 'GET',
    dataType: 'jsonp',
    async: false,
    error: function (xhr, status) {
        alert(status);
    },
    success: function (result) {
        alert("Callback done!");
        // grid.dataBind(result.results);
        // grid.dataBind(result);
    }
});

谢谢,这就是我的情况。如果在 AJAX 调用完成之前页面进行了回发,就会出现这种情况。调用通常会很快失败,所以我只能在页面回发之前看到错误消息。 - DrewB
如果您使用服务工作者,快速响应可以更频繁地实现这一点。延迟模型避免了这种情况。请参见@MikeBaz的答案。 - Ray Foss

0
13年过去了,jQuery仍然存在!
任何遇到这个问题的人,请确保您的ajax响应具有“200 OK”的HTTP状态。否则,jQuery将不会将其视为成功!
请确保您的服务器脚本在请求和响应过程之间没有重定向。例如:中间件、其他相关函数、路由规则等。

0

这种情况刚好发生在我的一个同事身上,所以我想我也可以分享一下我的解决方案。

我们可以看到ajax调用被执行了,并且在Fiddler中可以看到正确的响应(状态码200 / 完全有效的JSON),但它永远不会触发错误、成功或完成回调。将async: false添加到ajax调用中可以使其工作,但这并不是一个真正的解决方案。此外,在ajax调用之后直接放置一个警报(没有async: false),并在显示警报后等待几秒钟,会以某种方式强制ajax回调函数工作。非常奇怪...

结果发现,带有ajax调用的函数绑定到了type="submit"的输入框上,这就是这种奇怪行为的根源。将输入框更改为type="button"即可纠正它。


0
这不适用于较新版本的jQuery,但在我的情况下,我正在维护一个使用jQuery v3.2.1的旧产品。我尝试使用一个异步回调,但在早期版本中不支持。没有错误或任何提示,回调函数只是没有执行。
一个解决方法是使用setTimeout函数:
success: function (data) {
  setTimeout(async function() {
    await someAsyncOperation(data);
  }, 0);
}

相关链接:jQuery Ajax异步函数在成功时不触发

-1

使用Jquery Ajax调用具有多个参数的servlet时,即使调用成功,也无法调用成功或错误。它绑定到提交按钮上。更改后返回成功事件。

以下是我的参考代码,以防有人需要参考。

$(document).ready( function () {    
    $("#buttonSave").click(function() {
        alert('incustsave');
        var name = $("#custname").val();
        var gstnumber = $("#gstnumber").val();
        var custbizname = $("#custbizname").val();
        var email = $("#email").val();
        var address = $("#address").val();
        var street = $("#street").val();
        var city = $("#city").val();
        var zip = $("#zip").val();
        var phone = $("#phone").val();
        var country = $("#ctry").val();

        var inputArray = [name, gstnumber, custbizname, email, address, street, city, zip, phone, country];
        var Success = false;
        alert('added_button_and_dt');
        $.ajax({  
            type: "POST",
            url: "RegisterCustomerServlet",               
            data: {'input': inputArray},
            dataType: 'json',

            success: function (data) {
                alert('sucess');
            },
            error: function (e) {
                alert('error');
            }
        });
    });
});

使用Bootstrap3的HTML(按钮参考)

<!-- Button -->
<div class='wrapper text-center'>
    <div class="btn-group">
        <button type="button"  id="buttonSave" class="btn btn-primary">Save</button>
    </div>
</div>

Servlet 参考

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    HashMap<String,String>  map = new HashMap<String,String>();
    CustomerDAO custinfo = new CustomerDAO();
    Gson gson = new Gson();
    CustomerVO vo = new CustomerVO();

    String[] myJsonData = request.getParameterValues("input[]");
    logger.info("in custregisterjsoninput" + myJsonData[0] + myJsonData[2] + myJsonData[3] + myJsonData[4]);

    map.put("custname", myJsonData[0]);
    map.put("getsnumber", myJsonData[1]);
    map.put("custbizname", myJsonData[2]);

    map.put("email", myJsonData[3]);
    map.put("address", myJsonData[4]);
    map.put("street", myJsonData[5]);
    map.put("city", myJsonData[6]);          
    map.put("pincode", myJsonData[7]);
    map.put("mainphone", myJsonData[8]);
    map.put("country", myJsonData[9]);

    try {
        vo = custinfo.saveCustomerInfo(map);
    } catch (Exception e) {
        logger.info("aftercall"+e.getMessage());
        throw new ServletException(e);
    }  
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(Utility.convertPOJOtoJason(vo));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接