什么是跨域以及几种简朴解决方案

什么是跨域?

要邃晓什么是跨域之前,首先要邃晓什么是同源战略

同源战略就是用来限定从一个源加载的文档或剧本与来自另一个源的资本举行交互。那如何推断是不是是同源呢?

假如协定,端口(假如指定了)和主机关于两个页面是雷同的,则两个页面具有雷同的源,也就是同源。也就是说,要同时满足以下3个前提,才叫同源:

  1. 协定雷同
  2. 端口雷同
  3. 主机雷同

举个例子就一览无余了:

我们来看下面的页面是不是与 http://store.company.com/dir/index.html 是同源的?

  1. http://store.company.com/dir/index2.html 同源
  2. http://store.company.com/dir2/index3.html 同源 虽然在差别文件夹下
  3. https://store.company.com/secure.html 差别源 差别的协定(https)
  4. http://store.company.com:81/dir/index.html 差别源 差别的端口(81)
  5. http://news.company.com/dir/other.html 差别源 差别的主机(news)

所以当面临跨域题目标时刻,有什么处置惩罚方案呢?

跨域的几种处置惩罚方案

document.domain要领

我们来看一个详细场景:有一个页面 http://www.example.com/a.html ,它内里有一个iframe,这个iframe的源是 http://example.com/b.html ,很显然它们是差别源的,所以我们没法在父页面中操控子页面的内容。

处置惩罚方案以下:

<!-- b.html -->
<script>
document.domain = 'example.com';
</script>
<!-- a.html -->
<script>
document.domain = 'example.com';
var iframe = document.getElementById('iframe').contentWindow.document;

//背面就能够操纵iframe里的内容了...

</script>

所以我们只要将两个页面的document.domain设置成一致就能够了,要注重的是,document.domain的设置是有限定的,我们只能把document.domain设置成本身或更高一级的父域。

然则,这类要领只能处置惩罚主域雷同的跨域题目。

window.name要领

window对象有个name属性,该属性有个特性:即在一个窗口(window)的生命周期内,窗口载入的一切的页面都是同享一个window.name的,每一个页面临window.name都有读写的权限,window.name是耐久存在一个窗口载入过的一切页面中的,并不会因新页面的载入而举行重置。

我们来看一个详细场景,在一个页面 example.com/a.html 中,我们想猎取 data.com/data.html 中的数据,以下是处置惩罚方案:

<!-- data.html -->
<script>
window.name = 'data'; //这是就是我们须要通讯的数据
</script>
<!-- a.html -->
<html>
<head>
<script>
    function getData () {
        var iframe = document.getElementById('iframe');
        iframe.src = 'example.com/b.html'; // 这里让iframe与父页面同源
        
        iframe.onload = function () {
            var data = iframe.contentWindow.name; //在这里我们得到了跨域页面中传来的数据
        };
    }
</script>
</head>
<body>
</body>
</html>

JSONP要领

JONSP(JSON with Padding)是JSON的一种运用情势。基本道理以下:

<!-- a.html -->
<script>
    function dealData (data) {
        console.log(data);
    }
</script>

<script src='http://example.com/data.php?callback=dealData'></script>
<?php
    $callback = $_GET['callback'];
    $data = 'data';
    echo $callback.'('.json_encode($data).')';
?>

这时刻在a.html中我们得到了一条js的实行语句dealData('data'),从而达到了跨域的目标。

所以JSONP的道理实在就是应用引入script不限定源的特性,把处置惩罚函数名作为参数传入,然后返回实行语句,仔细阅读以上代码就能够邃晓内里的意义了。

假如在jQuery顶用JSONP的话就越发简朴了:

<script>
$.getJSON(''http://example.com/data.php?callback=?', function (data) {
    console.log(data);
});
</script>

注重jQuery会自动天生一个全局函数来替代callback=?中的问号,以后猎取到数据后又会自动烧毁,实际上就是起一个暂时代办函数的作用。$.getJSON要领会自动推断是不是跨域,不跨域的话,就挪用一般的ajax要领;跨域的话,则会以异步加载js文件的情势来挪用JSONP的回调函数。

总结

除了上述要领外,HTML5还新增了一个window.postMessage()要领,有兴致的能够自行查阅。

末了,处置惩罚跨域题目另有一个更通用更壮大的CORS要领,我零丁把它拿出来总结了一篇文章:跨域题目标基础处置惩罚方案CORS

    原文作者:刘宁Leo
    原文地址: https://segmentfault.com/a/1190000013278814
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞