跨域的一些方法

Posted 前端小小小小小小小白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域的一些方法相关的知识,希望对你有一定的参考价值。

一、什么是跨域
理解跨域首先要理解同源策略,它是浏览器对js施加的一种安全限制。所谓同源是指协议、域名、端口必须相同。浏览器在请求数据时都要遵循同源策略,那么凡是发送请求的URL中协议、域名、端口三者之中的一点不同时,就叫做跨域。


二、jsonp

1、什么是jsonp

JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,是被包含在函数调用中的JSON。它由两部分组成:回调函数和数据。

2、jsonp跨域的原理

直接用XMLHttpRequest请求不同域上的数据是不可以的,但是在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。利用<script>标签的src引入一个js文件,动态创建script标签,当js文件载入成功后,执行我们在src属性中指定路径后方的回调函数,并且把请求到的json数据作为参数传入。

(在客户端注册一个callback并传给服务器,服务器端生成 json 数据,然后以 javascript 语法的方式生成一个function ,将 json 数据直接以入参的方式放置到 function 中,返回给客户端。浏览器解析script标签并执行返回的 javascript 文档,动态执行将返回的数据作为参数的callback回调。)

3、jsonp的用法:

<script type="text/javascript">
function jsonpCallback(jsondata){
console.log(jsondata);
}
</script>
<script src="https://api.douban.com/v2/book/searchq=javascript&count=1&callback=jsonpCallback"></script>
运行得到的数据应该是带有回调函数的,类似jsonpCallback(jsondata)才是正确的;


如果是jQuery,可以使用$.getJSON(url,data,callback(data,status,xhr))方法:

$.getJSON(‘https://api.douban.com/v2/book/searchq=javascript&count=1&callback=?‘,function (data) {
console.log(data);
});


jquery会自动生成一个全局函数来替换callback=?中的问号,获取到数据后自动销毁。$.getJSON()方法自动判断是否跨域,不跨域调用ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

注意:jsonp除了前端处理外,还需要服务器端的配合。jsonp只支持get请求,不支持post请求。jsonp不容易判断请求结果,一般结合定时。

三、document.domain跨子域

修改document.domain的方法只适用于主域相同不同子域的框架间的交互:


四、window.name

window.name在一个窗口的生命周期内,窗口载入的所有的页面都共享这个name,持久存在在一个窗口载入过的所有页面中,不会因为新页面的载入而进行重置,所以利用它的这个属性就可以实现跨域获取数据。

比如在页面 A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后(iframe.onload),页面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出iframe的window.name的值了(因为A中的window.name和iframe中的window.name互相独立的,所以不能直接在A中获取window.name,而要通过iframe获取其window.name)。

用法:

比如http://www.example.com/a.html页面,这个页面里的xx.js想获取http://www.other.com/b.html里的数据,b.html里要把数据赋值给window.name,在a.html中使用一个隐藏的iframe充当中间人的角色,由iframe获取b.html中的数据。

b.html中:

<script type="text/javascript">
window.name = ‘hello wx!‘; // 把传输的数据赋值给window.name
</script>
a.html中:

<script type="text/javascript">
var state = 0,
iframe = document.createElement(‘iframe‘),
loadfn = function() {
if (state === 1) {
var data = iframe.contentWindow.name; // 读取数据
//console.log(data);
} else if (state === 0) {
state = 1;
iframe.contentWindow.location = "http://www.example.com/xx.html"; // 设置代理文件
}
};
iframe.src = ‘http://b.com/data.html‘;
if (iframe.attachEvent) {
iframe.attachEvent(‘onload‘, loadfn);
} else {
iframe.onload = loadfn;
}
document.body.appendChild(iframe);
</script>

 

以上是关于跨域的一些方法的主要内容,如果未能解决你的问题,请参考以下文章

关于ajax跨域的一些解决方案

thinkphp5 关于跨域的一些坑,附上解决办法(比较全面了)

解决chrome跨域问题

如何用CORS来解决JS中跨域的问题

对于未知数量的域,跨域的 $.post 的替代/修复是啥

前端跨域