什么是跨域?为什么要跨域呢?听说jsonp能.
为什么jsonp能跨域呢?什么时候使用jsonp?怎么使用jsonp?
接下来,谢尔铎来和你一起研究研究.
关于跨域
就是由于JavaScript同源策略的限制,使得a.com域名下的js无法操作b.com或c.a.com域名下的对象或数据。简单理解同一个 域名、相同端口、相同协议!
同源策略
就是阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。即受到请求的URL的域必须与当前Web页面的域相同, 离来自不同源的内容,以防止它们之间的操作。
“同源策略”的意义
“同源策略”有效地阻止了一些危险行为,如你同时打开多个网站时,其中有一个木马网站,那么木马网站就有可能窃取其他 信息或资料(因为多个网站间是可以相互通信的),给网上用户带来很大的泄密风险。正是由于有了“同源策略”,才大大降 由于木马网站与其他你浏览的网站不同源,因此无法相互间通信访问、获取数据等。
“同源策略”的不足
虽然“同源策略”在一定程度上保护了用户的网络安全,但如果有时就是需要让www.aaa.com取得www.bbb.com上的数据,同 策略”造成无法从自己信任的其他网页上取得数据。
jsonp 实现跨域是相对来说的 有些跨域问题 ,是js本身就解决不了的
是的,恍然大悟的时刻到了,其实JSONP就是利用这一点(可以算是漏洞、也可以算是技术吧)实现了跨域访问数据。说白了,其实JSONP跨域技术本质上是创建标 指向跨域地址而实现跨域获取数据。
JSONP原理
JSONP(JSON with Padding),就是异步请求跨域的服务器端时,不是直接返回数据,而是返回一个js方法,把数据作为参数
只是跨域传递数据那么这种方式是比较好的。字面理解就是:利用内填充的原理,将json填充到一个box中的概念。 原理总是又饶又拗口,直接来个简单的小例子吧!
在www.aaa.com页面中:
1
2src="http://www.bbb.com/jsonp.js">3
4functionjsonp(json){
5alert(json[‘name’]);
6}
7
1jsonp({'name':'twobin','age':24});
则页面会弹出“twobin”,是否更为直观好理解一点呢!
我们可以取到www.bbb.com/jsonp.js,里面是一个名为jsonp的函数(这个函数名称可以自定义),这个函数也会被加载到w加载完成后,就应该执行jsonp了,然后我们在www.aaa.com定义jsonp函数,这个函数里写一些处理数据的语句。这样其实 跨域访问数据了,这也就是JSONP的工作原理了。而“JSON with Padding”的意思,就是jsonp(json)中的json,即
1{'name':'twobin','age':24}
这个JSON对象被包在jsonp这个函数中当作参数来被处理,而“JSON with Padding”这个词很形象地形容了这个过程。JSONP实例—百度搜索联想
在百度首页搜索框中其实就用到了JSONP技术,如我们在百度搜索框中输入json,则下拉框会自动给出多个相关的联想词, 实是从另一个不同源的域名中获取的数据,通过JSONP技术获取这些数据后实时的显示在下拉列表中。
本文就是仿百度搜索联想实现一个采用JSONP技术的例子。
(1)解析数据地址首先需要知道联想词数据的来源地址。在Chrome中的JavaScript控制台下,查看Network,在百度搜索框中输入关键词,如“
到输入“json”关键词后传回的数据。
其中,联想词数据的地址是:
http://suggestion.baidu.com/su?wd=json&p=3&cb=window.bdsug.sug&sid=&t=1383046774638
简单解析下该地址,搜索关键字wd=‘json’,cb是一个回调函数,该回调函数是我们取到数据要后执行的函数,在百度搜索中window.bdsug.sug。点击该地址链接,可以得到下列数据:
既然是利用标签的src地址来获取跨域数据,就不能将src地址写死,而应该根据需求动态获取跨域数据,因此需要根标签后动态指定src地址。
1varoScript=document.createElement('script');
2oScript.src='http://suggestion.baidu.com/su?wd='+oTxt.value+'&p=3&cb=baidu&from=superpage';
3document.body.appendChild(oScript)
注意:动态生成标签时会产生代码冗余,由于我们每输入一个字符,页面就会动态生成一个标签,一旦我们动态常创建的标签太多了以后.会占用大量内存,并产生代码冗余.所以标签不用了,就及时删除.
1if(oScript){
2document.body.removeChild(oScript);
3}