在介绍jsonp之前,先来聊一聊浏览器的同源策略。
关于同源策略的由来
1995年,同源策略被引入到浏览器中,其目的是为了保护用户的数据安全。
同源策略主要做了以下几点的限制:
(1) 非同源站点上的Cookie、LocalStorage 和 IndexDB 无法读取。
(2) 非同源站点上面的DOM节点 无法获得。
(3) AJAX 请求不能发送给非同源站点。
试想一下,如果没有这些限制,你在浏览网站的时候,你的cookie可以被别人随意读取,别人可以直接用你的身份去登陆网站,肆意的发挥;你页面的dom结构还可以被别人控制,肆意修改,就问你一句:怕不怕?
反正
我怕!
但是,任何事情都有两面性,浏览器禁止页面脚本跨域请求提高了安全性的同时,也带来一些不方便。
很多时候我们确实需要跨站去请求一些资源,那浏览器同源策略的限制是不是有限苛刻了?
其实细心的小伙伴们已经发现,浏览器在为我们关闭一扇门的同时,给我们打开了一扇窗,带有src属性的img标签,你随便在src里面写上任意一个网站的图片地址,就可以获取这个图片的数据,说明它是不受同源策略限制的。script标签也是一样,又比如link标签,我们的css可以引入外部站点的css文件,获取对方站点的css文件数据。
接下来,我们要介绍的jsonp就是利用script标签的src不受跨越限制特性来实现的。
jsonp的实现原理
写js的时候,我们会在script标签里面引入我们需要的js文件,有自己网站上的,也有别的网站上的,不管哪个网站上的js文件,只要引入了,都可以去运行,丝毫不受同源策略的影响。
利用这个特性,我们就开始写我们的代码了:
先从一段简单的代码开始:
(1)在http://a.com下新建http://a.com/test.html文件,代码如下:
(2)在b.com下面新建文件http://b.com/test.js文件,代码如下:
(3)访问http://a.com/index.html文件,页面上会弹出“111”
此时此刻,我们的这个小例子就已经实现了跨域访问数据了,这是很多人会想,http://b.com/test.php下面的数据我如何拿到呢?光弹出有什么用?我需要操作这个返回结果呀?
别急,我们继续往下看:
(1)现在我们修改http://b.com/test.js文件,代码如下:
(2)修改http://a.com/test.html文件,代码如下:
(3)访问http://a.com/test.html,输出如下:
看,现在http://b.com/test.js里面的数据我们拿到了,跨域操作就是这么简单,3步就完成了。
不过善于思考的朋友又会问,你这样复制的方式,属于全局变量的操作方式,这种方式不好。
#新手朋友们可能不知道为啥全局变量不好,这里稍稍解释下,例如你引入了a.js文件,a.js文件里面写了var a='面面包';又引入了b.js文件,但是b.js文件里面写了var a='屎';然后当你运行alert(a)的时候居然弹出了“屎”,你点了一份面包,别人送你一坨屎,你觉得这样好吗?所以说全局变量是个很讨厌的东西。
那么,不用赋值的方式,我们如何把数据获取到呢?
(1)现在我们修改http://b.com/test.js文件,代码如下:
(2)修改http://a.com/test.html文件,代码如下:
(3)访问http://a.com/test.html,输出如下:
现在不用担心全局污染了,我们通过函数调用的方式获取到了我们想要的数据。
不过又有朋友要问了,你这样页面一访问就加载数据,如果我希望手动触发事件之后才去获取数据呢?
好,咱继续往下看:
(1)现在我们修改http://b.com/test.js文件,代码如下:
(2)修改http://a.com/test.html文件,代码如下:
(3)访问http://a.com/test.html,点击一下按钮”点击“,效果如下:
通过动态生成script标签的方式,我们实现了手动获取数据的方式。
以上就是今天要介绍的jsonp的原理和实现方式,接下来,我会介绍jquery下jsonp的写法以及通过jsonp跨域实现sso单点登陆。