7

我正在尝试将 jsonp 与 jQuery 一起使用,但我得到了不一致的行为。有时脚本有效,有时无效;我真的不明白为什么。

这是 Chrome 可能显示的错误:

Uncaught TypeError: Property 'jQuery18208278296771459281_1362854738133' of object [object Object] is not a function

在以下示例中,我只是尝试检查应用程序是否在线。但是这种不一致的行为可能会发生在其他类似的 ajax 调用上:

     $.ajaxSetup({
        error: function (req, status, ex) {},
        success: function (data, status, req) {},
        timeout: 2000,
        crossDomain: true,
        contentType: "application/json",
        dataType:"jsonp",
        url: "http://myUrl.com/ping.php?preventCache="+new Date()
    });
    return $.ajax();

服务器端的 PHP 文件也很简单:

<?php
header("Content-Type: application/javascript; charset=UTF-8");
echo $_GET['callback'];
?> ({ "status": "online" })
4

3 回答 3

15

当您的 JSONP 调用超时(根据您的线路,为两秒timeout: 2000)时,您将获得此行为,但数据在超时发生后到达。

JSONP 不使用普通的 XmlHTTPRequest。要执行 JSONP,jQuery 会在您的文档中插入一个脚本标签并创建一个临时函数来处理脚本标签加载(函数名称是错误消息中的那个长随机字符串)。

当您发生超时并且脚本尚未完成加载时,jQuery 会丢弃临时函数。在那之后的某个时间,脚本标签完成加载,并尝试调用该函数——但为时已晚,该函数已被删除。因此错误。

延长超时时间可能会减少错误,但基本问题是您无法取消脚本标签的加载。如果它没有出错,那么它总是有可能比你的超时时间长一点。据我所知,这没有很好的解决方案。您可以告诉 jQuery 使用显式命名的函数作为 JSONP 回调而不是自己创建,但是您需要自己跟踪事物是否超时。您可以使用 CORS,这是另一回事。

可能你最好的选择就是忍受它。

于 2013-11-21T05:34:49.657 回答
5

你的问题不太清楚,当我尝试使用相同的回调函数名称两次时,我得到了同样的错误。在任何情况下,这都是在 jquery 中调用 jsonp 的方式:

      var mycallback = 'c'+Math.floor((Math.random()*100000000)+1);
      $.ajax({
                   type: 'GET',
                    url: URL,
                    async: true,
                    jsonpCallback: mycallback,
                    contentType: "application/json",
                    dataType: 'jsonp'

       }).done(function(json){
           console.log(json);
                    callback(json);
       }).fail(function(f){
           console.log("f");
                    console.log(f.status);
       }).always(function(){
                   // console.log('complete');
      }); 
于 2013-03-22T08:32:11.407 回答
2

检查您的脚本是否连续多次发出相同的 AJAX 请求。

我有一个错误的事件处理程序,它同时触发了两个请求,这导致了同样的问题。

(我假设您调用 $.ajaxSetup 一次):看起来您打算为您的 ping 调用应用缓存破坏器,但在 $.ajaxSetup 中执行此操作可能会产生相反的效果,因为 URL 将为所有后续请求固定。

于 2013-03-15T10:56:14.657 回答