我们在开发中,经常会遇到跨域请求数据问题,那么什么是跨域呢?跨域就是js在不用域之间的数据传输或者通信,比如你在使用ajax从另外一个域请求数据,或者你的页面引入了iframe,要从iframe中获取数据的时候,就是跨域。简单一点的说,判断是否跨域,就看协议、域名、端口,这三个中只要有一个不同,就都属于不同的域。
<script> function do(jsondata){ //处理数据 } </script> <script src="http://exampleData/data.php?callback=do"></script>
由此就可以看出jsonp的原理就是利用script引入js文件,文件加载成功后执行url中指定的函数,我们需要获取的json数据将会作为参数传入。不过如果数据地址是别人的文件,自己无法操控,那么就得按照提供数据的一方的数据模式来处理。所以使用jsonp方法处理跨域,是需要服务器端的配合。
也可以使用jquery封装$.getJSON()的方法,这个方法很便利,看一下代码:
<script> $.getJSON('http://exampleData/data.php?callback=?’,function(jsondata){ //处理数据 }); </script>
jquery会自动生成一个全局函数来替换callback=?中的问号,获取到数据后又会自动销毁。$.getJSON方法会自动判断是否跨域,不跨域,就调用普通的ajax方法;跨域,则会以异步加载js文件的形式来调用jsonp的回调函数。
二、使用window.name解决跨域
window.name的性质是,在一个窗口的生命周期内,窗口载入的所有页面都是共享一个name,而且对name都有读写的权限。而且name并不会因为有新页面的载入而重置,是一直存在在窗口中的。即使是在一个页面中载入了另外一个不同域的页面,这个name的值只要之前没有修改,那也是不会变的。
那么就可以利用这特性来解决跨域问题。
比如从www.example.com/a.html中获取www.data.com/b.html中的数据,我们可以用一个隐藏的iframe标签来加载b页面,再在a页面里获取iframe的数据。
首先要在b.html中设置一下:
<script>
window.name="a页面需要获取的json数据或者字符串";
</script>
a.html中的代码为:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>解决跨域问题</title> <style type="text/css"> #ifarme{ display:none; } </style> </head> <body> <iframe src="http://www.data.com/b.html" frameborder="0" onload="getData()" id="ifarme"></iframe> </body> <script type="text/javascript"> function getData(){ var iframe = document.getElementById("iframe"); iframe.onload = function(){ var data = iframe.contentWindow.name; console.log(data); } ifarme.src="about:blank";//这里的src的页面可以随意设置为与a.html同源的页面,空白页about:blank也行。只有同源,a.html才能访问到iframe里面的东西。 } </script> </html>
跨域的原理基本就是这样,可以根据自己的需求改写封装。作为数据中转的ifame,可以在获取完数据之后销毁。