时间:2021-07-01 10:21:17 帮助过:4人阅读
虽然后来解决了,但是对于喜欢解决问题的我,心里却一直耿耿于怀,必须得把这个研究透彻了,于是我开始翻阅资料,看到后面真有种豁然开朗的感觉,于是打算做个笔记与大家分享。
JSON和JSONP的区别
JSON和JSONP虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON是一种数据交换格式,而JSONP是一种跨域数据交互的协议,使用JSONP方法获取到的仍然是json格式的数据。
说白了,用JSON来传数据,靠JSONP来跨域
。
JSONP详细阐述
我们都知道,一个页面的ajax只能获取和此页面同域的数据。
,所以当我们需要跨域获取数据的时候就需要使用到JSONP方法来获取了。
如下图所示,就是使用json格式获取跨域数据返回的错误提示:
那么该如何解决呢?使用框架的前端童鞋们可能都有自己相应的办法,比如jquery就是把dataType设为jsonp
就能解决了,但是我们在使用的时候有没有想过,为什么这样就能解决呢?中心思想又是什么呢?
下面就开始为大家详细阐述,首要思想就是利用scirpt标签来引入跨域的数据。我们从最开始慢慢来深入jsonp的过程。
引导步骤1
编写b.com/b.js
内容:
然后编写a.com/a.html
内容:
运行a.html,结果很明显,肯定会弹出hello。
引导步骤2
修改b.com/b.js
文件内容:
然后修改a.com/a.html
内容:
运行a.html 结果是弹出‘hello world'。这个应该也毫无疑问。
引导步骤3
让我们再看一下上面的步骤2,b.js中的‘hello'就是b.com域名下的数据了,而能够在a.com/a.html中执行显示出来,这不就已经实现了跨域请求数据了
吗?
另外,因为script标签中的src 不一定要指向js文件,而可以指向任何地址。
所以,我们把上面步骤2中a.html的内容:,我们把其中的
b.js
改成b.html
或者b.json
等等都是可以的,执行都能正常返回。
引导步骤4
上面的数据都是静态的,是在文件内写死的,所以并不能满足我们的需求了吧。。。因为我们ajax请求数据是实时变化的,所以我们要把数据变成动态的了。
我们可以让script表器去调用一个动态的页面(接口),去实现获取动态数据,这里就想到了回调函数
.
编辑a.com/a.html
页面内容:
我们在src引用地址中加了?callback=myFunction
,意思是把显示数据的函数也动态的传入了。
使用jsonp方法获取数据,还有一个要点就是后端接口也要支持jsonp才行
,比如下面一段代码就是让返回的数据变成jsonp的格式,请继续看:(此处使用.net语言作为例子)
代码的意思很简单,就是获取调用函数的参数。如果这里调用b.aspx?callback=myFunction
的话,则会返回myFunction('hello')
,如果后端代码给data赋值一个变量,这里的‘hello'则变成了动态的数据了。
引导步骤5
再看上面的步骤,虽然获取的数据是动态的了,但在页面上引入一个script标签,却只能执行一次,获取一次,显然还是不能满足需求的。所以我们在需要的时候,就得动态的添加一次这样的script标签。
所以我们在这里需要封装一个函数:
需要调用的时候,就去执行:
addScript('b.com/b.aspx?callback=myFunction'); function myFunction(data){//定义处理数据的函数 alert(data); }
ok,上面的过程就是jsonp的原理,我们不必去记住那些令人纠结不清的定义,只要看一遍这个过程,我相信就能明白其中的精髓了吧。
jquery实现跨域
jquery跨域方法
使用jquery非常方便,那么它是怎么实现这个转化的呢?下面我们来看看这部分的jquery源码。
jq实现jsonp源码分析
我贴出网上给的jquery实现jsonp部分的源码分析:
上面的代码稍显复杂,但是我们挑拣重要的看就好了。
我们来分析一下这个过程,其实这个过程也就是上面我提出问题的答案
了:
这里执行代码之后,其实就是判断是否配置了dataType: 'jsonp',如果是jsonp协议,则要在url上加callback=jQueryxxx(函数名),jquery会把url转化为:http://b.com/b.json?callback=jQueryxxx
,然后再在html中插入,加载完b.json这个文件后,就会执行jQueryxxx这个回调函数,而且此时这个函数里面已经存在了动态数据(json格式数据),所以在页面上执行的时候就能够随心所欲的处理数据了,但是也别忘了后端也要支持jsonp格式才行。所以这样就达到了跨域获取数据的功能。
原生js封装jsonp
这是我自己写的一个原生js实现jsonp获取跨域数据的方法。
我们只需要调用jsonp函数就能够跨域获取数据了。比如:
再说几点注意的地方:
使用jsonp方法时,在控制台的network-JS
中才能找到调用的接口,不再是XHR类了。由于页面渲染的时候script只执行一次,而且动态数据需要多次调用,所以在插入使用之后需要删除,并且要初始化回调函数。原生js实现时,最好加一个请求超时的功能,方便调试。
总之jsonp就是一种获取跨域json数据的方法。