使用jQuery连续发起jsonp请求失败的缘由

jQuery的 jsonp 你们应该是十分熟悉了。php

曾遇到过这样的需求ajax

一、但愿请求几个类似的内容添加到页面json

二、请求的内容必定时间内是固定不变的,但愿作个缓存。缓存

因而脑子一拍写下了相似这样的代码 复制代码服务器

for(var i = 0; i < 3; i++){
    $.ajax({
        url:'.../return.php?num='+i,
        dataType: 'jsonp',
        jsonp: 'callback',
        jsonpCallback: 'dosome',
        cache: true
    }).done(function(re){
        console.log(re);
    }).fail(function(){
        console.log('fail');
    });
}

复制代码函数

结果却老是只有一个成功并报错jsonp

Uncaught TypeError: dosome is not a functionurl

百思不得其解,不是有一个成功了吗?dosome怎么就不是函数了? 无奈之下花了大心思和时间在localhost上研究了jQuery的jsonp原理。code

设置服务器返回以下回调函数

<?php 
    echo 'dosome("num='.$_GET['num'].'");';
?>

获得返回以下

仔细翻看源码,在1.11.3版本发现

原来每次jsonp请求,jQuery都自动先把callbackName函数注册到window,又在返回后把window[ callbackName ]改回来。

因而同步执行完for循环发送请求后,处理第一个返回时就把window[ callbackName ]改为了 undefined,后续的返回都没法处理了。

我一阵郁闷,反正这个函数也没执行什么,不改回去不行吗?

惋惜,我仍是太天真,其实不改回去也同样没法正常获得想要的结果的。

我的理解,jQuery的jsonp原理大体以下

每次jsonp请求,都是新建一个处理函数把返回内容赋值到局部变量responseContainer,而后在调用注册的回调函数以对应的局部变量responseContainer[0]为参数执行。

当使用不一样的处理函数名时,一切相安无事(当咱们不写jsonpCallback时,jQuery会自动生成惟一不一样的函数名)。就如同上面的dosome1,2,3,各自引用并处理。

而使用一样的函数名时,循环时window['dosome']顺序被赋值,最终指向最后一个处理函数(如图中红线),其余的都被回收了。第一个返回时执行,把内容赋值到最后一个局部变量。

这样,第一个请求会拿不到返回内容从而fail,而最后一个请求的回调却处理了不是本身请求的内容。

相关文章
相关标签/搜索