2011-10-07 86 views
13

我建立了一个Ajax调用(jQuery的1.6.2),看起来的测试案例,如:处理jQuery.ajax错误跨域JSONP调用

jQuery(document).ready(function($) { 
    var test = function(x) { 
     $.ajax({ 
      url: 'http://www.someotherdomain.com/test.php', 
      data: { x: x }, 
      dataType: 'jsonp', 
      crossDomain: true, 
      success: function(data) { 
       console.log(data.name); 
      }, 
      error: function() { 
       x++; 
       test(x); 
      } 
     }); 
    }; 
    test(1); 
}); 

和相应的test.php文件的样子:

if (5 > $_GET[ 'x' ]) { 
    header('HTTP/1.1 503 Service Temporarily Unavailable'); die(); 
} else { 
    header('content-type: application/x-javascript'); 
    echo $_GET[ 'callback' ] . '({"name":"Morgan"})'; 
} 

即使jQuery documentation表明,对于JSONP错误处理程序调用时从来没有发射,这个脚本作品一样我打算。它会对test.php进行四次“不成功”调用,返回503错误,然后test()递归调用自身递增x,直到ajax调用“成功”并将数据输出到控制台。

所以我的测试用例上述作品,但我实际的代码不能正常工作,这看起来更像是以下几点:

jQuery(document).ready(function($) { 
    var completed = 0; 
    var fiftystates; // assume an array of state objects 
    var updateState = function(index, state) { 
     var d = index % 5; // for subdomains sub0, sub1, sub2, sub3, sub4 
     $.ajax({ 
      url: 'http://sub' + d + '.mydomain.com/update_state.php', 
      data: { state: state.id }, 
      dataType: 'jsonp', 
      crossDomain: true, 
      success: function() { 
       completed++; 
       var complete_percent = completed/fiftystates.length * 100; 
       $('#progressbar').progressbar('value', completed_percent); 
      }, 
      error: function() { 
       updateState(index, state); 
      } 
     }); // end ajax 
    }; // end updateState 
    $(fiftystates).each(updateState); 
}; 

正如你可以看到,这个循环通过5个不同的子域这实际上是只是同一个域的镜像,但由于update_state.php最多可能需要30秒才能完成,因此需要25分钟的时间才能完成不到3分钟。问题在于服务器砰砰声导致某些ajax请求失败并出现503错误。在我的测试用例中,这个处理没有问题,但在第二个示例中,错误处理程序似乎永远不会被调用。

我不明白为什么测试用例能够像我期望的那样工作,而第二个不能。有任何想法吗?

+0

试图改变最多的jQuery 1.6。 4结果相同 – morphatic

+0

是否可以使用php'header()'返回503的行为与“实际”503的行为不同?我检查了这两种情况下的HTTP头,他们看起来和我一样... – morphatic

+0

在第一个示例中,您每次在错误处理程序中增加x(x ++;)。在你的第二,你不增加索引++;这是我能看到的唯一明显的区别。 – Kato

回答

2

在您的测试情况下,你改变德值x献给每一个呼叫...

在其他代码你发送相同的索引值。这将返回相同的结果,而不是“旋转”,通过子域...

error: function() { 
     index++; 
     updateState(index, state); 
    } 
+1

index参数自动递增最后一行的jQuery.each()函数调用。好想法,但我不认为这是问题。 – morphatic

+0

我知道索引是通过.each()函数调用改变的。不过这并不影响在错误情况下调用的索引。对于数组中的每个状态,您都可以调用该函数,该函数在发生错误时调用自身... – blindfold

2

如果碰巧你使用IE浏览器来测试第一种情况下,可能FF或Chrome测试第二种情况则可能是原因。错误和全局回调不会针对jQuery.ajax函数记录的跨域JSON/JSONP类型调用。但是,我注意到他们仍然在IE中调用,我认为这与jQuery使用IE XMLHttpRequest进行调用有关。

看来有人慷慨地创建了处理与这里提供JSONP请求错误插件:http://code.google.com/p/jquery-jsonp/

3

它应该在格式是这样的:

$.ajax({ 
    type: "POST", 
    url: 'http://servername/WebService.svc/GetData?callback=?', 
    dataType: 'jsonp', 
    success: function (data) { 
     //do stuff 
    }, 
    error: function (msg, b, c) { 
    //alert error 
    } 
}); 
+0

JSONP不能用于跨域进行POST请求。 jQuery会自动将其更改为GET请求。 – cesarislaw

+2

检查jquery网站“注意:此处理程序不会被要求跨域脚本和跨域JSONP请求。” – shereifhawary

0
function AjaxRequest(url, params){ 

    return $.ajax({ 
     url:   url, 
     data:   params, 
     dataType:  'jsonp', 

     /* Very important */ 
     contentType: 'application/json', 
    }); 
} 

var test = function(x) { 

    AjaxFeed('http://servername/WebService.svc/GetData', {x: x}) 

    /* Everything worked okay. Hooray */ 
    .done(function(data){ 

     console.log(data); 
    }) 

    /* Oops */ 
    .fail(function(jqXHR, sStatus, oError) { 

     console.log(arguments); 
    }); 
} 

jQuery(window).load(function() { 

    test('test'); 
}