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,一经查实,立即删除!

相关文章

创建 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;接下来我们查看如何制作搜索栏以及分类区制作。 首先我…

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;设置其上下…

利用百度云盘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. 椭球面积计算原理 <

实践 Neutron 前的两个准备工作 - 每天5分钟玩转 OpenStack(78)

上一节配置了 linux-bridge mechanism driver&#xff0c;本节再做两个准备工作&#xff1a; 1. 检视初始的网络状态。2. 了解 linux bridge 环境中的各种网络设备。 初始网络状态 我们首先考察实验环境最初始的网络状态。随着学习的深入&#xff0c;我们会对网络不断进行新的配…

《iVX 高仿美团APP制作移动端完整项目》04 美食页 标题、搜索、商家标题制作

点击整个专栏查看其它系列文章 &#xff08;系列文章更新中…&#xff09;&#xff1a;《iVX 高仿美团APP制作移动端完整项目》 项目界面预览&#xff1a; 一、美食页顶部商家页制作 1.1 页面主格调确认 该美食页为首页中美食按钮点击后进入的页面。该页面分为顶部的标题、搜…

利用浏览器调试功能 计算 百度网盘 文件数量

“百度网盘”程序做的比较烂&#xff0c;以百度的技术实力按说不应该如此。真正试了就知道真的不怎么样。为了统计百度网盘的文件写了以下脚本&#xff0c;仅供参考&#xff1a; var root "";//指定目录&#xff0c;空取当前目录 var totalCount 0; var startTime …

就在刚刚,HTTP/3 正式发布了!

经过了多年的努力&#xff0c;在 6 月 6 号&#xff0c;IETF &#xff08;互联网工程任务小组&#xff09; 正式发布了 HTTP/3 的 RFC&#xff0c; 这是超文本传输协议&#xff08;HTTP&#xff09;的第三个主要版本&#xff0c;完整的 RFC 超过了 20000 字&#xff0c;非常详细…

通渭县义岗川镇之行(2020年11月19日)

2020年11月18日&#xff0c;应邀前往通渭县义岗川镇老家&#xff0c;经过了3个小时的自驾车程&#xff0c;夜幕降临时刻到达了美丽的义岗川小镇。 义岗川镇&#xff0c;隶属甘肃省定西市通渭县&#xff0c;地处通渭县城最北部&#xff0c;东南与寺子川乡毗连&#xff0c;南邻北…

《iVX 高仿美团APP制作移动端完整项目》05 美食页商家推荐内容、分类、推荐商家制作

这一节我们将讲解美食页下半部分内容制作&#xff1a; 一、完善店铺推荐 接下来继续制作以下内容&#xff1a; 1.1 满减信息 现在咱们在对应的商家行中添加一个行&#xff0c;命名为满减&#xff0c;并且对应的更改高度为包裹&#xff1a; 随后更改其背景色、字体颜色使…

利用浏览器调试功能 计算 百度网盘 文件数量 V2

最近需要统计百度网盘里文件的数量&#xff0c;百度网盘又没有提供这样的功能&#xff0c;因此之前自己写了段脚本进行查验&#xff0c;见《利用浏览器调试功能 计算 百度网盘》。之后发现每个目录最多文件数只有1000&#xff0c;因此研究了哈百度的接口&#xff0c;重新对脚本…

Single Number II(LintCode)

Single Number II Given 3*n 1 numbers, every numbers occurs triple times except one, find it. Example Given [1,1,2,3,3,3,2,2,4,1] return 4 Challenge One-pass, constant extra space. 统计每一位上的1出现的次数&#xff0c;然后模3 &#xff0c; 题目上的3 * n 1给…