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请求失败的原因的更多相关文章

  1. FastAdmin 源码分析:jQuery 含逗号的选择器

    FastAdmin 源码分析:jQuery 含逗号的选择器 在 FastAdmin 你常常会看到以下 jQuery 选择器的代码. if ($(".datetimepicker", ...

  2. jQuery源码分析之=>jQuery的定义

    最近写前段的代码比较多,jQuery是用的最多的一个对象,但是之前几次看了源码,都没搞清楚jQuery是怎么定义的,今天终于看明白怎么回事了.记录下来,算是一个新的开始吧. (文中源码都是jQuery ...

  3. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  4. jQuery1.11源码分析(7)-----jQuery一些基本的API

    这篇文章比较繁杂,主要就是把jQuery源码从上到下列出来,看我的注释就好了. jQuery源码对各种加载器做了处理. //阅读这个源码是请先了解一下概念,即时函数,工厂模式 (function( g ...

  5. jQuery1.11源码分析(6)-----jQuery结构总揽

    (在看以下内容之前请先对原型链有一定的了解,比如:prototype是对象还是函数?) 在看jQuery的其他源码之前,必须对jQuery的数据结构有一定的了解. jQuery的核心很简单,jQuer ...

  6. 【SpringCloud Eureka源码】从Eureka Client发起注册请求到Eureka Server处理的整个服务注册过程(下)

    目录 一.Spring Cloud Eureka Server自动配置及初始化 @EnableEurekaServer EurekaServerAutoConfiguration - 注册服务自动配置 ...

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

    一.DispatcherServlet的初始化 在我们第一次学Servlet编程,学java web的时候,还没有那么多框架.我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根 ...

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

    上一章大概讲了前置过滤器和请求分发器的作用,这一章主要是具体分析每种对应的处理方式 $.ajax()调用不同类型的响应,被传递到成功处理函数之前,会经过不同种类的预处理(prefilters). 预处 ...

  9. jQuery1.11源码分析(8)-----jQuery调用Sizzle引擎的相关API

    之所以把这部分放在这里,是因为这里用到了一些基本API,前一篇介绍过后才能使用. //jQuery通过find方法调用Sizzle引擎 //jQuery通过find方法调用Sizzle引擎 jQuer ...

随机推荐

  1. webstorm使用技巧

    WebStorm快捷键收集:模式visual studio 代码提示:ctrl + alt + 空格 代码补全:alt + / 代码换行:ctrl + shift + 上下箭头 重新运行:ctrl + ...

  2. mybatis generator配置生成代码的问题

    接触第二种orm两天下来,一脸懵逼.mybatis是大多数公司所推崇的,相比于hibernate性能较为好的,操作更为方便的轻量级工具,所以小富就搞起这个orm.好吧,都说mybatis有个配置可以自 ...

  3. Ruby FFI 入门教程

    FFI是一个可以让用户使用Ruby调用C代码的gem.如果你需要执行一些系统底层调用,或者做一些高性能运算的话,FFI是一个很不错的选择. 1. 安装 执行gem install ffi即可.非常标准 ...

  4. 12个免费的 Twitter Bootstrap 后台模板

    在互联网上提供很多免费的 Bootstrap 管理后台主题.所有你需要做的就是将它们下载并安装它们,这真的不是什么难事.问题是如何寻找到能够完美符合您的网站需求的主题.当然,你可以自己制作自定义的主题 ...

  5. Spring Setter Injection and Constructor Injection

    Setter Injection AppContext.xml <?xml version="1.0" encoding="UTF-8"?> < ...

  6. java中复制对象通过反射或序列化

    在使用缓存读取数据后修改发现缓存被修改.于是找了下复制对象的方法. 关于对象克隆 按我的理解,对象是包含引用+数据.通常变量复制都是将引用传递过去.比如: Person p1 = new Person ...

  7. 解决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 ...

  8. C#序列化s实体类成Xml,去除空格、换行符以及命名空间

    序列化实体类成为一个干净的Xml,不带空格.换行符以及命名空间 /// <summary> /// 序列化成XML /// </summary> /// <typepar ...

  9. MD5编码工具类 MD5Code.java

    代码如下: package com.util; /** * MD5编码工具类 * http://www.cnblogs.com/sosoft/ */ public class MD5Code { st ...

  10. iOS阶段学习第28天笔记(UIView的介绍)

    iOS学习(UI)知识点整理 一.关于UIVIew 的介绍 1)概念:UIView 是用于装载并展示各类控件的大容器,是iOS中所有UI控件的基类 2)UIView  初始化实例代码 UIView * ...