深入源码分析使用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 ...
随机推荐
- webstorm使用技巧
WebStorm快捷键收集:模式visual studio 代码提示:ctrl + alt + 空格 代码补全:alt + / 代码换行:ctrl + shift + 上下箭头 重新运行:ctrl + ...
- mybatis generator配置生成代码的问题
接触第二种orm两天下来,一脸懵逼.mybatis是大多数公司所推崇的,相比于hibernate性能较为好的,操作更为方便的轻量级工具,所以小富就搞起这个orm.好吧,都说mybatis有个配置可以自 ...
- Ruby FFI 入门教程
FFI是一个可以让用户使用Ruby调用C代码的gem.如果你需要执行一些系统底层调用,或者做一些高性能运算的话,FFI是一个很不错的选择. 1. 安装 执行gem install ffi即可.非常标准 ...
- 12个免费的 Twitter Bootstrap 后台模板
在互联网上提供很多免费的 Bootstrap 管理后台主题.所有你需要做的就是将它们下载并安装它们,这真的不是什么难事.问题是如何寻找到能够完美符合您的网站需求的主题.当然,你可以自己制作自定义的主题 ...
- Spring Setter Injection and Constructor Injection
Setter Injection AppContext.xml <?xml version="1.0" encoding="UTF-8"?> < ...
- java中复制对象通过反射或序列化
在使用缓存读取数据后修改发现缓存被修改.于是找了下复制对象的方法. 关于对象克隆 按我的理解,对象是包含引用+数据.通常变量复制都是将引用传递过去.比如: Person p1 = new Person ...
- 解决The file “FWLifeApp” couldn’t be opened because you don’t have permission to view it.问题
The file “FWLifeApp” couldn’t be opened because you don’t have permission to view it问题是因为项目文件中的Bundl ...
- C#序列化s实体类成Xml,去除空格、换行符以及命名空间
序列化实体类成为一个干净的Xml,不带空格.换行符以及命名空间 /// <summary> /// 序列化成XML /// </summary> /// <typepar ...
- MD5编码工具类 MD5Code.java
代码如下: package com.util; /** * MD5编码工具类 * http://www.cnblogs.com/sosoft/ */ public class MD5Code { st ...
- iOS阶段学习第28天笔记(UIView的介绍)
iOS学习(UI)知识点整理 一.关于UIVIew 的介绍 1)概念:UIView 是用于装载并展示各类控件的大容器,是iOS中所有UI控件的基类 2)UIView 初始化实例代码 UIView * ...