前言
我工作以来接触的第一个项目就是前后端分离的,前端静态文件有自己独立域名,通过接口来获取数据进行渲染等操作。
跨域的方法不需要多言,随便一搜,就有很多,但最常用不外乎jsonp和CORS。jsonp着重于前端,也算是前端Hack技巧,CORS重于后端,服务端需要配置的地方会较多。
这篇解析一下jsonp的实现原理。
基本原理
基本原理很容易说明白,在html页面中有一些标签是不受跨域限制的,比如img,script,link等。如果把我们需要的数据,放在一个js文件里面,这时,我们就能突破浏览器同源的限制。
创建script标签
《高性能JavaScript》中提到了动态脚本元素,作者写道:
1、文件在该元素被添加到页面时开始下载。这种技术的重点在于:无论何时启动下载,文件的下载和执行过程不会阻塞页面其他进程。
2、使用动态脚本节点下载文件时,返回的代码通常会立刻执行(除了Firefox和Oprea,它们会等待此前所有动态脚本节点执行完毕。)当脚本自执行时,这种机制运行正常。
引用1保证了JSONP请求的时候不会阻塞主线程,引用2保证了JSONP代码在加载完成后,立刻自执行时不会出错。
callback
服务端在接收到GET请求之后,通常要判断是否有callback参数,如果有,则需要在返回的数据外面加上一个方法名和括号。例如,发起如下请求:
http://www.a.com/getSomething"htmlcode">jsonp0({code:200,data:{}})很明显,由于这是在动态加载的Script标签中包含的内容,那么这就是一段自执行代码,这段代码只有一个函数被调用———jsonp0。
当然,有执行,则必须先创建,否则就会报错。创建这一步,就需要在调用前执行。
具体实现如下:
function jsonp (url, successCallback, errorCallback, completeCallback) { // 声明对象,需要将函数声明至全局作用域 window.jsonp0 = function (data) { successCallback(data); if (completeCallback) completeCallback(); } // 创建script标签,并将url后加上callback参数 var script = document.createElement('script') , url = url + (url.indexOf('"color: #ff00ff">完善一下在实际情况下,通常会有许多个jsonp的请求同时调用,
那么既然jsonp0就能满足我们的需要,为什么常常看到jsonp1,jsonp2等等依次累加的代码呢?
这是因为,请求可能是很多个异步进行。在第一次执行jsonp方法时,window.jsonp0是函数A,此时去加载js文件,在js未加载完毕的情况下,又调用了一次jsonp方法,此时,window.jsonp0指向了函数B。那么等到两次的js加载完毕以后,都会执行第二次的回调。
所以,我们需要对callback的名字做一个区别处理,累加就能满足需要。
修改一下代码:
var jsonpCounter = 0; function jsonp (url, successCallback, errorCallback, completeCallback) { var jsId = 'jsonp' + jsonpCounter++; // 声明对象,需要将函数声明至全局作用域 window[jsId] = function (data) { successCallback(data); if (completeCallback) completeCallback(); clean(); } // 创建script标签,并将url后加上callback参数 var script = document.createElement('script') , url = url + (url.indexOf('"htmlcode">var jsonpCounter = 0; function jsonp (url, successCallback, errorCallback, completeCallback, timeout) { // 略去上面写过的代码 var timeout = timeout || 10000 , timer ; if (timeout) { timer = setTimeout(function () { if (errorCallback) { errorCallback(new Error('timeout')); } clean(); }, timeout) } function clean () { script.parentNode.removeChild(script); window[jsId] = function(){}; if (timer) clearTimeout(timer); } }这样,基本上就完成了jsonp的全部功能,剩下的可能需要做一些兼容的修改,才算是一个完整的jsonp方法。
REFER
《高性能JavaScript》
npm上的一个jsonp实现,JSONP
以上这篇基于JSONP原理解析(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
标签:JSONP,原理
帝王谷资源网 Design By www.wdxyy.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 群星2013-青春缤纷辑压箱宝大公开3CD2[新加坡限量版][WAV整轨]
- 林育群.2013-BalladShow(日本版)【环球】【WAV+CUE】
- 陈加洛.1992-痛到感觉不到【宝丽金】【WAV+CUE】
- 群星.2023-宿命之敌电视剧原声带【韶愔音乐】【FLAC分轨】
- 東京事変-大発見[FLAC+CUE]
- 椎名林檎-三文ゴシップ[FLAC+CUE]
- 2024年08月04日
- 裘德《裘德「最后的水族馆」演唱会LIVE》[320K/MP3][228.89MB]
- 裘德《裘德「最后的水族馆」演唱会LIVE》[24bit 48kHz][FLAC/分轨][2.08G]
- 基因三重奏《如果你什么都不说 音乐会现场录音》[320K/MP3][145.37MB]
- 孟庭苇.1996-月亮说话(2020环球24KGOLD限量版)【上华】【WAV+CUE】
- 群星.1997-新艺宝优质音响系列·国语精选监听版【新艺宝】【WAV+CUE】
- 阿桑.2005-寂寞在唱歌(星外星引进版)【华研国际】【WAV+CUE】
- 基因三重奏《如果你什么都不说 音乐会现场录音》[FLAC/分轨][287.43MB]
- 蔡题谦《我爱你,却依然要看你走》[320K/MP3][88.65MB]