深入源码分析使用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,而最后一个请求的回调却处理了不是自己请求的内容。
深入源码分析使用jQuery连续发起jsonp请求失败的原因的更多相关文章
- FastAdmin 源码分析:jQuery 含逗号的选择器
FastAdmin 源码分析:jQuery 含逗号的选择器 在 FastAdmin 你常常会看到以下 jQuery 选择器的代码. if ($(".datetimepicker", ...
- jQuery源码分析之=>jQuery的定义
最近写前段的代码比较多,jQuery是用的最多的一个对象,但是之前几次看了源码,都没搞清楚jQuery是怎么定义的,今天终于看明白怎么回事了.记录下来,算是一个新的开始吧. (文中源码都是jQuery ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- jQuery1.11源码分析(7)-----jQuery一些基本的API
这篇文章比较繁杂,主要就是把jQuery源码从上到下列出来,看我的注释就好了. jQuery源码对各种加载器做了处理. //阅读这个源码是请先了解一下概念,即时函数,工厂模式 (function( g ...
- jQuery1.11源码分析(6)-----jQuery结构总揽
(在看以下内容之前请先对原型链有一定的了解,比如:prototype是对象还是函数?) 在看jQuery的其他源码之前,必须对jQuery的数据结构有一定的了解. jQuery的核心很简单,jQuer ...
- 【SpringCloud Eureka源码】从Eureka Client发起注册请求到Eureka Server处理的整个服务注册过程(下)
目录 一.Spring Cloud Eureka Server自动配置及初始化 @EnableEurekaServer EurekaServerAutoConfiguration - 注册服务自动配置 ...
- 2.SpringMVC源码分析:DispatcherServlet的初始化与请求转发
一.DispatcherServlet的初始化 在我们第一次学Servlet编程,学java web的时候,还没有那么多框架.我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根 ...
- jQuery源码分析系列(34) : Ajax - 预处理jsonp
上一章大概讲了前置过滤器和请求分发器的作用,这一章主要是具体分析每种对应的处理方式 $.ajax()调用不同类型的响应,被传递到成功处理函数之前,会经过不同种类的预处理(prefilters). 预处 ...
- jQuery1.11源码分析(8)-----jQuery调用Sizzle引擎的相关API
之所以把这部分放在这里,是因为这里用到了一些基本API,前一篇介绍过后才能使用. //jQuery通过find方法调用Sizzle引擎 //jQuery通过find方法调用Sizzle引擎 jQuer ...
随机推荐
- Project简介
Microsoft Project (Project)是一个国际上享有盛誉的通用的项目管理工具软件,凝集了许多成熟的项目管理现代理论和方法,可以帮助项目管理者实现时间.资源.成本的计划.控制,协助项目 ...
- RWD Table Patterns – 响应式表格解决方案
在显示复杂的表格数据的时候,相信 Web 开发人员都碰到过显示不下的情况.RWD Table Patterns 是一个很好的响应式表格解决方案.它采用移动优先以及渐进增强的设计理念,在不支持响应式的浏 ...
- javascript学习总结(一):基础知识。
1 数据类型a.数据类型共有7种,字符串(string).数字(number).布尔(boolean).数组(array).对象(object).Null.Undefined. 其中布尔(逻辑)类型只 ...
- HTML5 Web 客户端五种离线存储方式汇总
最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及Fi ...
- 从.net转型,聊聊最近一些面试,薪资和想法
上一个星期,一篇名为<.net估计要写在你手里了>几乎点燃了整个园子,有人群情激愤了,有人点赞的,有人上去打算喷博主个体无完肤的,总之,这篇博客很成功的引起一些.net 从业者的思考,也包 ...
- Redis代码阅读之Hacking Strings
Hacking Strings The implementation of Redis strings is contained in sds.c ( sds stands for Simple Dy ...
- asp.net获取站点根目录下子目录的名称
使用Visual Studio建立一个.aspx文件(Web Forms),例如hovertree.aspx,在页面上加入一个ListBox代码如下: <asp:ListBox runat=&q ...
- 15天玩转redis —— 第六篇 有序集合类型
今天我们说一下Redis中最后一个数据类型 “有序集合类型”,回首之前学过的几个数据结构,不知道你会不会由衷感叹,开源的世界真好,写这 些代码的好心人真的要一生平安哈,不管我们想没想的到的东西,在这个 ...
- MEF入门之不求甚解,但力求简单能讲明白(三)
上一篇我们已经获得了制定类型的实例,但我们还无法对其进行有效的控制. 我们用ExportMetadata属性可以对具体的某个实例做标记,相当于命名.这么理解不知道对否. 在IPart项目中添加一个接口 ...
- 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native
[源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...