跨域利器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/lab/a.js |
同一域名下不同文件夹 |
允许 |
|
http://www.a.com:8000/a.js |
同一域名,不同端口 |
不允许 |
|
http://www.a.com/a.js |
同一域名,不同协议 |
不允许 |
|
http://www.a.com/a.js |
域名和域名对应ip |
不允许 |
|
http://www.a.com/a.js |
主域相同,子域不同 |
不允许 |
|
http://www.a.com/a.js |
同一域名,不同二级域名 |
不允许 |
|
http://www.cnblogs.com/a.js |
不同域名 |
不允许 |
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>
1 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地址。
1 var oScript = document.createElement('script');
2 oScript.src = 'http://suggestion.baidu.com/su?wd='+oTxt.value+'&p=3&cb=baidu&from=superpage';
3 document.body.appendChild(oScript);
注意:动态生成<script>标签时会产生代码冗余,由于我们每输入一个字符,页面就会动态生成一个<script>标签,一旦我们输入的字符繁多且不同,页面就会实时生成众多的冗余标签,因此需要在我们输入字符前检查是否存在冗余的<script>标签,如果存在则将其删除,从而避免代码冗余。
if(oScript){
document.body.removeChild(oScript);
}
最终JS:
//利用JSONP实现搜索联想,当在搜索框中输入关键词时,会出现实时对应的联想词,这些联想词数据来自另一个域名http://suggestion.baidu.com/,因此可以利用JSONP实现跨域调用数据
window.onload = function ()
{
var oTxt = document.getElementById('baiduTxt');
var oUl = document.getElementById('baiduUl');
var oScript = null ;
oTxt.onkeyup = function()
{
oUl.innerHTML = '' ;
//避免造成代码冗余,出现众多script标签(由于每输入一个字符,就会动态生成script标签,因此每次需要清除上一次遗留下的script标签)
if(oScript)
{
document.body.removeChild(oScript);
}
oScript = document.createElement('script');
//其中‘wd’是搜索的关键字,‘cb’是一个回调函数,该回调函数是我们取到数据要后执行的函数,oScript.src中cb=baidu即表示取到数据后执行baidu函数
oScript.src = 'http://suggestion.baidu.com/su?wd='+oTxt.value+'&p=3&cb=baidu&from=superpage';
document.body.appendChild(oScript);
}
};
//回调时调用的函数,将取得的联想词展示出来
function baidu (json)
{
var oUl = document.getElementById('baiduUl');
for(var i=0;i<json.s.length;i++)
{
var oLi = document.createElement('li');
oLi.innerHTML = json['s'][i];
oUl.appendChild(oLi);
}
};
Html:
<body>
<div id="warp">
<h2>百度搜索联想</h2>
<input type="text" id="baiduTxt" />
<ul id="baiduUl">
</ul>
</div>
</body>
跨域利器JSONP(转)的更多相关文章
- jQuery(三) javascript跨域问题(JSONP解决)
加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...
- 浏览器同源策略,跨域请求jsonp
浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...
- 跨域Ajax -- jsonp和cors
跨域Ajax - jsonp - cors 参考博客: http://www.cnblogs.com/wupeiqi/articles/5703697.html http://www.cnblogs. ...
- jquery跨域解决方案JSONP
1.在互联网中我们的计算机是通过IP来定位的,但是IP比较难记忆,因此通过domain name(域名)来取代IP 2.什么是跨域? (1)默认浏览器为了安全问题,禁止了xmlhttprequest跨 ...
- Ajax跨域:Jsonp实例--百度搜索框下拉提示
Ajax跨域:Jsonp实例--百度搜索框下拉提示 一.总结 一句话总结:a.找好接口:b.用script标签的src引入文件(json数据):c.定义及实现上一步引入文件中的函数 1.如何找到一个网 ...
- JS跨域:jsonp、跨域资源共享、iframe+window.name
JS跨域:jsonp.跨域资源共享.iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html JS中的跨域 请求跨域有 ...
- 【记录】ajax跨域问题jsonp正确的使用方式
最近遇到ajax请求跨域问题,解决方案用jsonp,现记录如下: //跨域请求jsonp封装 function doJsonPostCallBack(type, url, data,async, ca ...
- cors跨域和jsonp劫持漏洞 和 同源策略和跨域请求解决方案
cors跨域和jsonp劫持漏洞: https://www.toutiao.com/a6759064986984645127/ 同源策略和跨域请求解决方案:https://www.jianshu.co ...
- 前端跨域解决方案: JSONP的通俗解说和实践
对于前端开发者而言,跨域是一个绕不开的话题.只有真正明白了各种方案的工作机制,才能针对性地进行跨域方案选型.本文将以探索者的视角,试图用最通俗的语言对一种"鼎鼎大名"的跨域解决方 ...
随机推荐
- JavaScript之With语句讲解
有了With 语句,在存取对象属性和方法时就不用重复指定参考对象,在 With 语句块中,凡是 JavaScript 不识别的属性和方法都和该语句块指定的对象有关.With 语句的语法格式如下所示:W ...
- ajax原理总结附简单实例及其优点
在工作中用了Ajax N多次了,也看过一些相关方面的书籍,也算是认识了它,但是一直没有认真总结和整理过相关的东东,失败! 近有闲情,将之总结如下: [名称] Ajax是Asynchronous Jav ...
- GIS数据格式topojson
Topojson源自于GeoJson,是D3中描述地理数据的格式,D3的作者觉得GeoJson太繁琐.同样的数据,TopoJson是GeoJson的1/5. 这里有一个转换TopoJson,GeoJs ...
- javascript document.write
在载人页面后,浏览器输出流自动关闭:在此之后,任何一个对当前页面进行操作的document.write()方法将打开—个新的输出流.它将清除当前页面内容(包括源文档的任何变量或值).document. ...
- 高达渐出现效果Shader
原地址: http://liweizhaolili.blog.163.com/blog/static/1623074420140591864/ 最近在玩游戏<高达破坏者>,里面的高达出现的 ...
- SQL技术内幕-8 使用WITH AS提高性能简化嵌套SQL
--本文来源:http://www.cnblogs.com/fygh/archive/2011/08/31/2160266.html 一.WITH AS的含义 WITH AS短语,也叫做子查询部分(s ...
- php怎么获取checkbox复选框的内容?
由于checkbox属性,所有必须把checkbox复选择框的名字设置为一个如果checkbox[],php才能读取,以数据形式,否则不能正确的读取checkbox复选框的值哦. <form n ...
- HDU 3790 最短路径问题(SPFA || Dijkstra )
题目链接 题意 : 中文题不详述. 思路 :无论是SPFA还是Dijkstra都在更新最短路的那个地方直接将花费更新了就行,还有别忘了判重边,话说因为忘了判重边WA了一次. #include < ...
- [你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望
发布日期:2009.05.22 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文开始,将以& ...
- BZOJ 1008: [HNOI2008]越狱 快速幂
1008: [HNOI2008]越狱 Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生 ...