js的跨域问题和解决办法

时间:2023-03-10 04:59:00
js的跨域问题和解决办法

我们在开发中,经常会遇到跨域请求数据问题,那么什么是跨域呢?跨域就是js在不用域之间的数据传输或者通信,比如你在使用ajax从另外一个域请求数据,或者你的页面引入了iframe,要从iframe中获取数据的时候,就是跨域。简单一点的说,判断是否跨域,就看协议、域名、端口,这三个中只要有一个不同,就都属于不同的域。

使用XMLHttpRequest请求不同域上的数据,是不可以的。下面是解决跨域获取数据和通信的几个方法。
一、jsonp解决跨域问题。
比如你有一个页面index.html,需要从不同的域里获取json数据,数据地址为“http://exampleData.com/data.php”,那么你就可以在html页面中这样写:
<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,可以在获取完数据之后销毁。