[转] 疯狂的JSONP

何为跨域?何为JSONP?JSONP技术能实现什么?是否有必要使用JSONP技术?

跨域

就是由于JavaScript同源策略的限制,使得a.com域名下的js无法操作b.com或c.a.com域名下的对象或数据。简单理解同一个域就是:相同域名、相同端口、相同协议!

同源策略

就是阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。即受到请求的URL的域必须与当前Web页面的域相同,意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。

“同源策略”的意义

“同源策略”有效地阻止了一些危险行为,如你同时打开多个网站时,其中有一个木马网站,那么木马网站就有可能窃取其他网站上关于你的信息或资料(因为多个网站间是可以相互通信的),给网上用户带来很大的泄密风险。正是由于有了“同源策略”,才大大降低了这种风险,由于木马网站与其他你浏览的网站不同源,因此无法相互间通信访问、获取数据等。

“同源策略”的不足

虽然“同源策略”在一定程度上保护了用户的网络安全,但如果有时就是需要让www.aaa.com取得www.bbb.com上的数据,同样是因为”同源策略”造成无法从自己信任的其他网页上取得数据。


URL


说明


是否允许通信


http://www.a.com/a.js
http://www.a.com/b.js


同一域名下


允许


http://www.a.com/lab/a.js
http://www.a.com/script/b.js


同一域名下不同文件夹


允许


http://www.a.com:8000/a.js
http://www.a.com/b.js


同一域名,不同端口


不允许


http://www.a.com/a.js
https://www.a.com/b.js


同一域名,不同协议


不允许


http://www.a.com/a.js
http://70.32.92.74/b.js


域名和域名对应ip


不允许


http://www.a.com/a.js
http://script.a.com/b.js


主域相同,子域不同


不允许


http://www.a.com/a.js
http://a.com/b.js


同一域名,不同二级域名


不允许


http://www.cnblogs.com/a.js
http://www.a.com/b.js


不同域名


不允许

注意:

(1)如果是协议和端口造成的跨域问题,那么对于JavaScript来说是无能为力的。

(2)在跨域问题上,域仅仅是通过“URL首部”来识别而不会去判断两个域是否对应同一个IP地址。

JOSNP

为了解决上面提到的需求,JSONP应运而生。其实JSONP在一定程度上弥补了AJAX的不足,即无法跨域获取数据。

那么JSONP这货到底是怎么来的,总不会是一群工程师拍脑袋拍出来的吧?其实,任何技术、任何事情的来源都是有根源可寻的。

不知大家是否注意到,你是如何引用jQuery写网页的呢?是否就是在页面中引入“<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>”即可,那么这其实是件很有意思的事情!大家是否发现http://code.jquery.com/与你的网站地址肯定是不同源的,那为什么还能在你的网页中引用到jQuery呢?

是的,恍然大悟的时刻到了,其实JSONP就是利用这一点(可以算是漏洞、也可以算是技术吧)实现了跨域访问数据。(其实有src属性的不止<script>标签,如<iframe>标签也是能够运用JSONP技术的)。说白了,其实JSONP跨域技术本质上是创建<script>标签,并通过其src指向跨域地址而实现跨域获取数据。

JSONP原理

JSONP(JSON with Padding),就是异步请求跨域的服务器端时,不是直接返回数据,而是返回一个js方法,把数据作为参数传过来。如果只是跨域传递数据那么这种方式是比较好的。字面理解就是:利用内填充的原理,将json填充到一个box中的概念。

原理总是又饶又拗口,直接来个简单的小例子吧!

在www.aaa.com 页面中:

<script type="text/javascript"
src="http://www.bbb.com/jsonp.js"></script>
<script type="text/javascript">
function jsonp(json){
    alert(json[‘name’]);
}
</script>

www.bbb.com/jsonp.js 中:

jsonp({‘name‘:‘twobin‘,‘age‘:24});

则页面会弹出“twobin”,是否更为直观好理解一点呢!

我们可以取到www.bbb.com/jsonp.js,里面是一个名为jsonp的函数(这个函数名称可以自定义),这个函数也会被加载到www.aaa.com。加载完成后,就应该执行jsonp了,然后我们在www.aaa.com定义jsonp函数,这个函数里写一些处理数据的语句。这样其实就简单地实现了跨域访问数据了,这也就是JSONP的工作原理了。而“JSON with Padding”的意思,就是jsonp(json)中的json,即

{‘name‘:‘twobin‘,‘age‘:24}

这个JSON对象被包在jsonp这个函数中当作参数来被处理,而“JSON with Padding”这个词很形象地形容了这个过程。

JSONP实例—百度搜索联想

在百度首页搜索框中其实就用到了JSONP技术,如我们在百度搜索框中输入json,则下拉框会自动给出多个相关的联想词,而这些联想词其实是从另一个不同源的域名中获取的数据,通过JSONP技术获取这些数据后实时的显示在下拉列表中。

本文就是仿百度搜索联想实现一个采用JSONP技术的例子。

1)解析数据地址

首先需要知道联想词数据的来源地址。在Chrome中的JavaScript控制台下,查看Network,在百度搜索框中输入关键词,如“json”,则获取到输入“json”关键词后传回的数据。

其中,联想词数据的地址是:

http://suggestion.baidu.com/su?wd=json&p=3&cb=window.bdsug.sug&sid=&t=1383046774638

简单解析下该地址,搜索关键字wd=‘json’,cb是一个回调函数,该回调函数是我们取到数据要后执行的函数,在百度搜索中回调后执行函数window.bdsug.sug。点击该地址链接,可以得到下列数据:

window.bdsug.sug({q:"json",p:false,s:["json格式","json在线解析","json解析","jsonp","jsonobject","json编辑器","jsonarray","json encode","json.stringify","json decode"]});
即这些联想词数据包含在函数window.bdsug.sug内作为参数传递给百度搜索首页,证明了JSONP跨域技术的可行性。

2)动态获取跨域数据

既然是利用<script>标签的src地址来获取跨域数据,就不能将src地址写死,而应该根据需求动态获取跨域数据,因此需要根据需求动态生成<script>标签后动态指定src地址。

var oScript = document.createElement(‘script‘);
oScript.src = ‘http://suggestion.baidu.com/su?wd=‘+oTxt.value+‘&p=3&cb=baidu&from=superpage‘;
document.body.appendChild(oScript);

注意:动态生成<script>标签时会产生代码冗余,由于我们每输入一个字符,页面就会动态生成一个<script>标签,一旦我们输入的字符繁多且不同,页面就会实时生成众多的冗余标签,因此需要在我们输入字符前检查是否存在冗余的<script>标签,如果存在则将其删除,从而避免代码冗余。

if(oScript){
    document.body.removeChild(oScript);
}

有博友提问:Google中的搜索联想貌似跟百度中的不一样?

Google中的搜索联想并不是通过callback回调函数执行的,如在google首页搜索框中输入“j”,则返回链接为:https://www.google.com.hk/complete/search?client=hp&hl=zh-CN&gs_rn=32&gs_ri=hp&cp=1&gs_id=65&q=j&xhr=t;显然google中的搜索联想是通过ajax技术实现无刷新实时返回联想数据的。

效果展示

http://jsfiddle.net/twobin/SUt7X/12/embedded/result,js,html,css/

时间: 2024-10-10 02:15:53

[转] 疯狂的JSONP的相关文章

原生jsonp跨域

<script> // jsonp跨域原生写法 var script = document.createElement('script'); script.src = 'http://192.168.7.16/kuayu/test02.php?callback=aa'; document.body.appendChild(script); //aa('后台数据') function aa(res) { alert(res.website); } </script>

跨域cors方法(jsonp,document.domain,document.name)及iframe性质

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作是不同的域. 下表给出了相对 http://store.company.com/dir/page.html 同源检测的结果: 要解决跨域的问题,我们可以使用以下几种方法: 1.通过jsonp跨域[解决ajax跨域] 在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的

ICO如此疯狂为哪般?

编者语: 独角兽一词起源于硅谷,是投资行业,尤其是风险投资业的术语,指的是那些估值超过十亿美元的创业公司.独角兽凤毛麟角,占创业公司总数的0.1%都不到.鑫根资本认为,一个独角兽能达到如此估值,肯定是掌握了某种颠覆时代的技术或模式,使得投资者趋之若鹜,它的诞生势必将带动其相关的产业链发生根本.敬请阅读! 文/卢菁.玟君(鑫根资本) 七月初,美国两家名不见经传的区块链技术公司Tezos和block.one成功完成了总值4亿美元的融资,而且,整个过程同VC.投行.华尔街.或金融证券监管都毫无关联.他

jsonp跨域

1 (function(window, document, undefined) { 2 'use strict'; 3 var jsonp = function(url, data, callback) { 4 var fnSuffix = Math.random().toString().replace('.', ''); 5 var cbFuncName = 'my_json_' + fnSuffix; 6 window[cbFuncName] = callback; 7 var quer

jsonp

由于浏览器中的同源策略,不同的域名,不同的协议,甚至不同的端口都无法请求数据.因此出现了浏览器跨域请求数据问题. Jsonp是解决跨域问题的一个非常流行的方法. JSONP(JSON with Padding),其实就是被包裹在函数调用中的JSON. callback({"name": "Kate"}); 1. JSONP原理 通过script标签进行跨域操作,载入的请求js文件中的内容会执行我们在url中指定的函数,并且,传入的参数,就是我们请求的数据. 2. J

JSON JSONP ajax

JSON 是一种数据格式 不是数据类型 也不是编程语言  JSON: JavaScript对象表示法 (JavaScript Object  Nonation)  与XML类似 比xml更小 更快 更易解析 JSONP :JSON+Padding (内填充)   把JSON当作内容添加到一个盒子里    用于 跨域              callback参数 什么是JSONP 首先提一下JSON这个概念,JSON是一种轻量级的数据传输格式,被广泛应用于当前Web应用中.JSON格式数据的编码

说一说javascript跨域和jsonp

同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议.域名.端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据. 要是想使用XMLHttpRequest或者常规的AJAX请求获取另一个站点的数据,浏览器会告诉你“XXXX is not allowed by Access-Control-Allow-Orign”. 因为同源策略的存在,防止了跨域访问的安全问题,但同时也损失了方便获取资源的便利. 跨域的src属性 世事又非绝对,浏览器还是允许几个元素跨域访问

51CTO学院教师节疯狂大让利活动

一颗心,承载着千万个理想.一句话,影响着千万个选择.寒来暑往,春夏秋冬,在这个最美的季节,有一个人,有一个节日属于他.9月10教师节即将来临,51CTO学院全体员工向各位讲师说声:                                                                                       "您辛苦了"~ 51CTO学院感谢两年来广大讲师对平台的鼎力支持,如今学院已成长为"中国最大的IT实战在线教育培训平台&quo

jquery ajax跨域的完美解决方法(jsonp方式)

ajax跨域请求的问题,JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式,接下来为大家详细介绍下客户端JQuery.ajax的调用代码 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发 JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式.分别是JQuery的 jquery.ajax jsonp格式和jquer