zepto源码研究 - ajax.js($.ajaxJSONP 的分析)

简要:jsonp是一种服务器和客户端信息传递方式,一般是利用script元素赋值src来发起请求。一般凡是带有src属性的元素发起的请求都是可以跨域的。

那么jsonp是如何获取服务器的数据的呢?

jsonp先将指定的一个函数名作为url后面的参数传递到服务器,服务器取得函数名并将要传递的数据形成json格式与函数名包装起来形成脚本传递给客户端执行。

/*** jsonp请求* @param options* @param deferred* @returns {*}*/$.ajaxJSONP = function(options, deferred){//未设置type,就走     ajax     让参数初始化.//如直接调用ajaxJSONP,type未设置if (!('type' in options)) return $.ajax(options)var _callbackName = options.jsonpCallback,     //回调函数名//得到最终的回调函数名,callbackName为回调函数名称callbackName = ($.isFunction(_callbackName) ?_callbackName() : _callbackName) || ('jsonp' + (++jsonpID)), //没有回调,赋默认回调script = document.createElement('script'),originalCallback = window[callbackName], //回调函数
    responseData,//中断请求,抛出error事件//这里不一定能中断script的加载,但在下面阻止回调函数的执行abort = function(errorType) {$(script).triggerHandler('error', errorType || 'abort')},xhr = { abort: abort }, abortTimeout//xhr为只读deferredif (deferred) deferred.promise(xhr)//监听加载完,加载出错事件$(script).on('load error', function(e, errorType){//清除超时设置timeout
      clearTimeout(abortTimeout)//删除加载用的script。因为已加载完了,.off()清除掉绑定到dom的所有事件
      $(script).off().remove()//错误调用errorif (e.type == 'error' || !responseData) {ajaxError(null, errorType || 'error', xhr, options, deferred)} else {//成功调用successajaxSuccess(responseData[0], xhr, options, deferred)}//回调函数window[callbackName] = originalCallbackif (responseData && $.isFunction(originalCallback))originalCallback(responseData[0])//清空闭包引用的变量值,不清空,需闭包释放,父函数才能释放。清空,父函数可以直接释放originalCallback = responseData = undefined})if (ajaxBeforeSend(xhr, options) === false) {abort('abort')return xhr}//回调函数设置,给后台执行此全局函数,数据塞入window[callbackName] = function(){responseData = arguments}//回调函数追加到请求地址script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName)document.head.appendChild(script)//超时处理,通过setTimeout延时处理if (options.timeout > 0) abortTimeout = setTimeout(function(){abort('timeout')}, options.timeout)return xhr}

$.ajaxJSONP(option,deffered) 这个方法在$.ajax中被调用,jsonp的请求和异步请求形式很像,但jsonp和ajax异步请求要严格去分开,jsonp是脚本加载形式。

但在zepto里面,jsonp和ajax请求做了形式上的融合,都是调用$.ajax方法,那么在$.ajax里面针对jsonp请求做出了哪些处理呢?

 var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url);if (hasPlaceholder) dataType = 'jsonp'//不设置缓存,加时间戳 '_=' + Date.now()// 当settings.cache === null时if (settings.cache === false || ((!options || options.cache !== true) &&('script' == dataType || 'jsonp' == dataType)))//Date.now() == 1471504727756settings.url = appendQuery(settings.url, '_=' + Date.now())//如果是jsonp,调用$.ajaxJSONP,不走XHR,走scriptif ('jsonp' == dataType) {if (!hasPlaceholder)  //判断url是否有类似jsonp的参数settings.url = appendQuery(settings.url,settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')return $.ajaxJSONP(settings, deferred)}

1:首先判断settings.dataType ,如果是jsonp格式则在url后面添加settings.jsonp = ?,默认添加callback=?。然后再调用$.ajaxJSONP方法。但这里为什么不直接调用$.ajaxJSONP而多出一步呢?这里会校验url,如果url后面有callback=?的形式,则dataType强制为jsonp。其实这里将hasPlaceholder作为$.ajaxJSONP的第三个参数,然后将settings.url的参数的处理放在$.ajaxJSONP内部进行,也是可以的。但作者为了能使$.ajaxJSONP重用并符合语义化要求,也就默认认定传入其中的settings参数带有callback=?的形式。

2:对于settings.url做appendQuery处理,其实就是保证settings.url后面一定得跟一个形式为callback=?的参数,如果之前url后面有,则不做处理。appendQuery是个工具,如果我们有在url后面加入参数的功能的时候,用它就可以了。

3:调用$.ajaxJSONP ,

流程总结如下:

1:获取url参数中的回调函数名callbackName,若没有则默认一个。

2:将callbackName函数对象保存起来。callbackName将在下面引用一个新的函数。

3:创建一个新脚本元素命名为script。

3:$(script).on("load error",function(){.....})

4:判断ajaxBeforeSend,是否中断请求

5:callbackName引用 function(){responseData = arguments},其作用是获取脚本里面的参数内容,然后以类似ajax的形式返回数据。

6:将options.url最后的callback=?换成callback=callbackName,并赋值给script.src。

7:设置超时处理

$(script).on("load error",function(){.....})中大致内容如下:

1:清除超时设置。2:off()清除掉script绑定的所有事件后清除掉remove()。

3:若e.type == 'error' 或者 responseData为空,触发ajaxError,否则触发ajaxSuccess。

4:将原来的callbackName传入responseData运行。

5:很重要的一步,释放内存。

 

以下是关于jsonp的服务器与客户端任务流程图


 

转载于:https://www.cnblogs.com/zhutao/p/5841893.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言试题十之将两个两位数的正整数a b合并形成一个整数放在c中。合并的方式是:将a数的十位和个位数依次放在c的十位和千位上,b数的十位和个位数依次放在c数的个位和百位上。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、 题目 请编写函…

Blazor University (27)路由 —— 检测导航事件

原文链接:https://blazor-university.com/routing/detecting-navigation-events/检测导航事件源代码[1]从 Blazor 访问浏览器导航是通过 NavigationManager 服务提供的。这可以使用 razor 文件中的 inject 或 CS 文件中的 [Inject] 属性注入到 Blazor 组件中。Locat…

创建 overlay 网络 - 每天5分钟玩转 Docker 容器技术(50)

上一节我们搭建好实验环境,配置并运行了consul,今天开始创建 overlay 网络。 在 host1 中创建 overlay 网络 ov_net1: -d overlay 指定 driver 为 overaly。 docker network ls 查看当前网络: 注意到 ov_net1 的 SCOPE 为 global&…

Js+Css 控制iframe内容自动缩放

竖屏横屏效果<div class"h5box"> <iframe src"http://player.youku.com/embed/XMTI4MjU5OTA3Mg" frameborder"0" width"1280px" height"720px"></iframe> </div><script type"tex…

西北冬日的校园很静谧,却不失韵味,因为有我们美好的青春!

冬日的校园&#xff0c;从枯黄的落叶开始。。。 落叶与栅栏情深。 冬日的篮球场上&#xff0c;不乏挥汗如雨的你&#xff0c;因为你是梦想与自由的追逐者&#xff0c;你可以战胜自己的懒惰。 我们的测量实训场&#xff0c;英雄的用武之地。 测桩&#xff1a;测量的控制点&#…

ps、top 、free查看用户资源信息

查看root用户的进程信息。 运行命令&#xff1a; ps -u root 查看oracle用户的进程信息。 运行命令&#xff1a; ps -u oracle 若查看现在的资源占用情况&#xff0c;如何呢&#xff1f; 运行命令&#xff1a; top 可以很详细的查看各个进程的运行情况。 若查看内存使用情…

《iVX 高仿美团APP制作移动端完整项目》02 搜索、搜索提示及类别需求分析思路及制作流程

点击整个专栏查看其它系列文章 &#xff08;系列文章更新中…&#xff09;&#xff1a;《iVX 高仿美团APP制作移动端完整项目》 项目界面预览&#xff1a; 一、搜索制作 在上一节中我们完成了标题头的制作&#xff0c;接下来我们查看如何制作搜索栏以及分类区制作。 首先我…

C语言试题十一之计算并输出下列多项式值:sn=(1-1/2)+(1/3-1/4)+…+(1/(2n-1)1/2n).

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、 题目 请编写函…

C#封装FluentValidation,用了之后通篇还是AbstractValidator,真的看不下去了

讲故事前几天看公司一个新项目使用了FluentValidation&#xff0c;大家都知道FluentValidation是一个非常强大的用于构建强类型验证规则的 .NET 框架&#xff0c;帮程序员解决了繁琐的校验问题&#xff0c;用起来非常爽&#xff0c;但我还是遇到了一件非常不爽的事情,如下代码所…

用批处理修复 win10 无法升级的问题

win10无法升级&#xff0c;通常的做法是先停止windows update 服务&#xff0c;删除临时缓存升级目录&#xff0c;重新启动升级服务。 写成一个批处理文件&#xff0c;直接用管理员身份运行一下就搞定。echo offfor /f "skip3 tokens4" %%i in (sc query wuauserv) d…

http304状态码缓存设置问题

当浏览器第一次加载资源的时候&#xff0c;返回一般为200&#xff0c;意思是成功获取资源&#xff0c;并会在浏览器的缓存中记录下max-age&#xff0c;第二次访问的时候&#xff1a;如果只是用浏览器打开&#xff0c;那么浏览器会去判断这个资源在缓存里有没有&#xff0c;如果…

10.2.0.5启动enterprise manager

10.2.0.5启动enterprise manager OEM作为一个实用工具&#xff0c;随着10g和11g的普及&#xff0c;OEM功能越来越强大&#xff0c;oem也应用越来越广泛。但是如果是10.2.0.5的版本&#xff0c;并且安装时间在2010年1月之后&#xff0c;可能会遇到OEM无法启动的情况&#xff0c;…

【数据结构与算法】多种语言(VB、C、C#、JavaScript)系列数据结构算法经典案例教程合集目录

文章目录1. 专栏简介2. 专栏地址3. 专栏目录1. 专栏简介 2. 专栏地址 「 刘一哥与GIS的故事 」之《数据结构与算法》 3. 专栏目录 【经典回放】多种语言系列数据结构算法&#xff1a;二叉树&#xff08;JavaScript版&#xff09;【经典回放】多种语言系列数据结构算法&#…

《iVX 高仿美团APP制作移动端完整项目》03 推介信息及推荐商家分析及制作

点击整个专栏查看其它系列文章 &#xff08;系列文章更新中…&#xff09;&#xff1a;《iVX 高仿美团APP制作移动端完整项目》 项目界面预览&#xff1a; 一、推荐信息制作 推荐信息与之前的标题下推荐信息制作类似&#xff1a; 此时依旧创建一个行&#xff0c;设置其上下…

C语言试题十二之m个人的成绩存放在score数组中,请编写函数function,它的功能是:将低于平均分的人数作为函数值返回,将低于平均分的分数放在below所指定的数组中。

✅作者简介:大家好我是码莎拉蒂,CSDN、华为云、阿里云、51CTO博客专家🥇🥇🥇 📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 1、 题目 m个人的成绩存放在score数组中,请编写函…

yum的三种方式

RHEL5中实现各种服务的准备条件&#xff1a;(一)、制作YUM本地源&#xff1a;YUM简介&#xff1a;YUM是Yellow dog Updater Modified的简称&#xff0c;yum是软件的仓库&#xff0c;它可以是http或ftp站点&#xff0c;也可以是本地软件池&#xff0c;但必须包含rpm的header&…

利用百度云盘API上传文件至百度云盘

一、获取Access Token示例 1. 请您将以下HTTP请求直接粘贴到浏览器地址栏内&#xff0c;并按下回车键。 https://openapi.baidu.com/oauth/2.0/authorize?response_typetoken&client_idL6g70tBRRIXLsY0Z3HwKqlRE&redirect_urioob&scopenetdisk 2、执行后&#x…

Docker 容器抓包

背景介绍程序在运行期间出现问题时&#xff0c;通常会通过抓包的方式来分析、定位问题。非容器应用一般可以通过 fiddler、wireshark 等工具进行抓包&#xff0c;那么&#xff0c;运行在容器的应用一般通过什么方式进行抓包呢&#xff1f;容器应用一般可以通过 tcpdump、ngrep …

服务发现与健康监测框架Consul-DNS转发的应用

关于Consul Consul是一个提供服务注册与发现&#xff0c;健康监测&#xff0c;Key/Value存储以及多数据中心存储的分布式框架。官网地址是https://www.consul.io/&#xff0c;公司初步应用后我们老大觉得这东西有点意思&#xff0c;随即有了翻译文档的想法&#xff0c;由于精力…

【ArcGIS风暴】ArcGIS10.6图斑椭球面积计算原理与方法

文章目录 1. 椭球面积计算原理2. ArcGIS计算图斑椭球面积3. ArcGIS计算图斑投影平面面积1. 椭球面积计算原理 <