深入源码分析使用jQuery连续发起jsonp请求失败的原因

jQuery的 jsonp 大家应该是十分熟悉了。
曾遇到过这样的需求
1、希望请求几个相似的内容添加到页面
2、请求的内容一定时间内是固定不变的,希望做个缓存。

于是脑子一拍写下了类似这样的代码

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‘);
    });
}

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

Uncaught TypeError: dosome is not a function

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

设置服务器返回如下

<?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,而最后一个请求的回调却处理了不是自己请求的内容。

时间: 2024-08-16 17:52:53

深入源码分析使用jQuery连续发起jsonp请求失败的原因的相关文章

jQuery源码分析系列(34) : Ajax - 预处理jsonp

上一章大概讲了前置过滤器和请求分发器的作用,这一章主要是具体分析每种对应的处理方式 $.ajax()调用不同类型的响应,被传递到成功处理函数之前,会经过不同种类的预处理(prefilters). 预处理的类型取决于由更加接近默认的Content-Type响应,但可以明确使用dataType选项进行设置.如果提供了dataType选项, 响应的Content-Type头信息将被忽略. 有效的数据类型是text, html, xml, json,jsonp,和 script. dataType:预期

jQuery源码分析之=&gt;jQuery的定义

最近写前段的代码比较多,jQuery是用的最多的一个对象,但是之前几次看了源码,都没搞清楚jQuery是怎么定义的,今天终于看明白怎么回事了.记录下来,算是一个新的开始吧. (文中源码都是jQuery-1.10.2版本的) 先上一段jQuery定义的源码,定义了jQuery为一个function 1 // Define a local copy of jQuery 2 jQuery = function( selector, context ) { 3 // The jQuery object

2.SpringMVC源码分析:DispatcherServlet的初始化与请求转发

一.DispatcherServlet的初始化 在我们第一次学Servlet编程,学java web的时候,还没有那么多框架.我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根据需要重写一下doGet,doPost方法,跳转到我们定义好的jsp页面.Servlet类编写完之后在web.xml里注册这个Servlet类. 除此之外,没有其他了.我们启动web服务器,在浏览器中输入地址,就可以看到浏览器上输出我们写好的页面.为了更好的理解上面这个过程,你需要学习关于Servl

jQuery 源码分析3: jQuery.fn/ jQuery.prototype

1 // 建立方法实例,提高方法访问的速度(避免在原型链上搜索) 2 3 var deletedIds = []; 4 var slice = deletedIds.slice; 5 var concat = deletedIds.concat; 6 var push = deletedIds.push; 7 var indexOf = deletedIds.indexOf; 8 var class2type = {}; 9 var toString = class2type.toString;

jQuery 源码分析4: jQuery.extend

jQuery.extend是jQuery最重要的方法之一,下面看看jQuery是怎样实现扩展操作的 1 // 如果传入一个对象,这个对象的属性会被添加到jQuery对象中 2 3 // 如果传入两个或多个对象,所有对象的属性会被添加到第一个对象中 4 5 // 如果想合并两个对象,则可以这样用: $.extend({}, obj1, obj2); 6 7 // 如果第一个参数是true,则执行深拷贝(迭代合并) 8 9 10 11 jQuery.extend = jQuery.fn.extend

六.jQuery源码分析之jQuery原型属性和方法

97 jQuery.fn = jQuery.prototype = { 98 constructor: jQuery, 99 init: function( selector, context, rootjQuery ) { }, 210 selector: "", 213 jquery: "1.7.2", 216 length: 0, 219 size: function() {}, 223 toArray: function() {}, 229 get: fun

妙味课堂jquery源码分析视频教程 jquery源码逐行分析分析

视频教程一共58课有10+G,解析的jquery版本未2.0版[娘的,我现在都还在用1.8,他们13年就已经在用2.0了!看来我是落后了!].本视频学习的好处不比那些实战的差!具体自己去感悟! 下载地址:百度网盘下载 原文地址:https://www.cnblogs.com/lomeixiok/p/11355306.html

jquery源码分析(二)——结构

再来复习下整体架构: jQuery源码分析(基于 jQuery 1.11 版本,共计8829行源码) (21,94)                定义了一些变量和函数jQuery=function(){} (96,280)        给jQuery添加一些方法和属性,jQuery.fn=jQuery.prototype(285,347)        extend:        jQuery的一些继承方法        更容易进行后续的扩展                       

jQuery.attributes源码分析(attr/prop/val/class)

回顾 有了之前的几篇对于jQuery.attributes相关的研究,是时候分析jQuery.attr的源码了 Javascript中的attribute和property分析 attribute和property兼容性分析 jQuery.access源码分析 结构 jQuery.fn.extend({ attr: function (name, value) { }, removeAttr: function (name) { }, prop: function (name, value) {