详细解读JSONP原理

下面小编就为大家推荐一篇基于jsonp原理解析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

前言

我工作以来接触的第一个项目就是前后端分离的,前端静态文件有自己独立域名,通过接口来获取数据进行渲染等操作。

跨域的方法不需要多言,随便一搜,就有很多,但最常用不外乎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?callback=jsonp0

登录后复制

那么服务端就会返回如下内容:

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('?') == -1 ? '?' : '&') + 'callback=jsonp0' ; script.src = url; document.head.parentNode.insertBefore(script, document.head); // 等到script加载完毕以后,就会自己执行}

登录后复制

上面基本上完成了一个jsonp方法的核心,此时,jsonp0是我们声明好的一个函数,如果服务端正常回传的时候,就会执行jsonp0函数,里面的successCallback回调也会执行。

完善一下

在实际情况下,通常会有许多个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('?') == -1 ? '?' : '&') + 'callback=' + jsId ; script.src = url; document.head.parentNode.insertBefore(script, document.head); // 等到script加载完毕以后,就会自己执行  //在执行完我们这个方法以后,会有很多script标签出现在head之前,我们需要手动的删除掉他们。 function clean () {  script.parentNode.removeChild(script);  window[jsId] = function(){}; }}

登录后复制

加入了累加和清理之后,还有一个重要的地方需要处理,就是错误回调。正常来说,我们通常请求jsonp时,会设定一个超时时间,如果超过这个时间以后,就抛出超时异常。

实现如下:

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

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在javascript中如何实现显式转换与隐式转换

在ReactNative中如何使用Redux架构

在Angular中使用MathJax碰到哪些问题?

使用NodeJS编写爬虫示例

以上就是详细解读JSONP原理的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2749248.html

(0)
上一篇 2025年3月8日 04:58:27
下一篇 2025年3月8日 04:58:38

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • VUE中如何使用Vue-resource完成交互

    本篇文章主要介绍了vue中使用vue-resource完成交互,内容挺不错的,现在分享给大家,也给大家做个参考。 本文介绍了VUE中使用Vue-resource完成交互,分享给大家,具体如下 使用vue-resource 引入vue-res…

    2025年3月8日 编程技术
    200
  • 关于AJax与Jsonp跨域访问的问题

    本文给大家汇总介绍了javascript的ajax,jquery的ajax以及利用jsonp实现跨域访问的问题,非常的细致全面,有需要的小伙伴可以参考下。 ####JavaScript的AJax AJAX即“Asynchronous Jav…

    编程技术 2025年3月8日
    200
  • jsonp如何进行跨域获取数据?(代码示例)

    jsonp如何进行跨域获取数据?本篇文章就给大家介绍jsonp进行跨域获取数据的方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 jsonp跨域获取数据小解 由于浏览器有同源策略,所以要想获取非同源(协议,域名,端口三者…

    编程技术 2025年3月8日
    200
  • JavaScript中typeof与instanceof之间的区别介绍(代码示例)

    本篇文章给大家带来的内容是关于javascript中typeof与instanceof之间的区别介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 JavaScript 中typeof 和 instanceof…

    编程技术 2025年3月8日
    200
  • javascript现继承的四种方式(代码示例)

    本篇文章给大家带来的内容是关于javascript现继承的四种方式(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 1、原型链继承 核心: 将父类的实例作为子类的原型 缺点:  父类新增原型方法/原型属性,子类都…

    编程技术 2025年3月8日
    200
  • 关于Jsonp跨域原理详解及简单应用

    浏览器的同源策略: 同源策略(Same Origin Policy)是一种约定,它是由Netscape提出的一个著名的安全策略,它限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。…

    2025年3月8日
    200
  • JSONP原理是什么?

    JSONP原理:首先在客户端注册一个函数;然后把函数的名字传给服务器;接着服务器成JSON数据,并以Javascript语法的方式,将数据传入客户端注册的函数中;最后在客户端注册函数中接收JSON即可。 JSONP JSONP(JSON w…

    2025年3月7日
    200
  • 12个vue高频原理面试题(附分析)

    本文分享12道高频vue原理面试题,覆盖了 vue 核心实现原理,其实一个框架的实现原理一篇文章是不可能说完的,希望通过这 12 道问题,让读者对自己的 vue 掌握程度有一定的认识(b 数),从而弥补自己的不足,更好的掌握 vue。 【相…

    2025年3月7日 编程技术
    200
  • 详解JS中的JSON和JSONP

    简单地使用json并不能支持跨域资源请求,为了解决这个问题,需要采用jsonp数据交互协议。众所周知,js文件的调用不受跨域与否的限制,因此如果想通过纯web端跨域访问数据,只能在远程服务器上设法将json数据封装进js格式的文件中,供客户…

    2025年3月7日
    200
  • 理解JavaScript闭包的基本原理

    javascript的闭包是一个相对复杂的概念。许多初学者都会在了解闭包之前觉得有些困难,但对于深入了解javascript和编写高质量代码来说,闭包是一个重要的概念。 什么是闭包?闭包是指一个函数可以访问其作用域之外的变量,即使在函数外部…

    编程技术 2025年3月7日
    200

发表回复

登录后才能评论