跨域与跨域访问

一、跨域问题

跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域。

注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。

二、解决办法

1.使用JSONP(只支持GET请求,不支持POST请求

对于JSONP不了解的,可以参看这篇文章:点击打开链接

客户端在使用Ajax访问是将dataType的值设为JSONP

服务器端

2.服务器代理

例如www.123.com/index.html需要调用www.456.com/server.php,可以写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,然后再返回给index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题。

3.使用CORS

服务器端设置请求头的拦截,以解决跨域问题

res.header("Access-Control-Allow-Origin", '*');   // 允许所有来源访问
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");  // 允许访问的方式
res.header("Access-Control-Allow-Credentials", true); //可以带cookies
res.header("Content-Type", "application/json;charset=utf-8"); 

4. postMessage

window.postMessage(message,targetOrigin) 方法是 HTML5 新引进的特性,可以向其它的 window 对象发送消息,无论这个 window 对象是属于同源或不同源。调用 postMessage 方法的 window 对象是指要接收消息的那一个 window 对象,该方法的第一个参数 message 为要发送的消息,类型只能为字符串;第二个参数 targetOrigin 用来限定接收消息的那个 window 对象所在的域,如果不想限定域,可以使用通配符 *。需要接收消息的 window 对象,可是通过监听自身的 message 事件来获取传过来的消息,消息内容储存在该事件对象的 data 属性中。

// 页面 http://www.test.cn/a.html 的代码:
<iframe src="http://test.cn/b.html" id="myIframe" onload="test()" style="display: none;">
<script>
    // 1. iframe载入 "http://test.cn/b.html 页面后会执行该函数
    function test() {
        // 2. 获取 http://test.cn/b.html 页面的 window 对象,
        // 然后通过 postMessage 向 http://test.cn/b.html 页面发送消息
        var iframe = document.getElementById('myIframe');
        var win = iframe.contentWindow;
        win.postMessage('我是来自 http://www.test.cn/a.html 页面的消息', '*');
    }
</script>


// 页面 http://test.cn/b.html 的代码:
<script type="text/javascript">
    // 注册 message 事件用来接收消息
    window.onmessage = function(e) {
        e = e || event; // 获取事件对象
        console.log(e.data); // 通过 data 属性得到发送来的消息
    }
</script>

5. document.domain

同源策略认为域和子域属于不同的域,如:child1.a.com 与 a.com,可以通过设置 document.damain='a.com',浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain='a.com'。特点如下:

(1) 只能在父域名与子域名之间使用,且将 xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com。
(2) 存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞。
(3) 只适用于 Cookie 和 iframe 窗口。

6. window.name

window 对象的 name 属性,在一个窗口(window)的生命周期内,窗口载入的所有的页面(不管是相同域的页面还是不同域的页面)都是共享一个 window.name 的,每个页面对 window.name 都有读写的权限,window.name 是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

// 页面 http://www.test.cn/a.html 的代码:

<iframe src="http://test.cn/b.html" id="myIframe" onload="test()" style="display: none;">
<script>
    // 2. iframe载入 "http://test.cn/b.html 页面后会执行该函数
    function test() {
        var iframe = document.getElementById('myIframe');
        
        // 重置iframe的onload事件程序,此时经过后面代码重置src之后,http://www.test.cn/a.html页面与该iframe在同一个源了,可以相互访问了
        iframe.onload = function() {
            var data = iframe.contentWindow.name; // 4. 获取 iframe 里的 window.name
            console.log(data); // hello world!
        };
        
        // 3. 重置一个与 http://www.test.cn/a.html 页面同源的页面
        iframe.src = 'http://www.test.cn/c.html';
    }
</script>


// 页面 http://test.cn/b.html 的代码:
<script type="text/javascript">
    // 1. 给当前的 window.name 设置一个 http://www.test.cn/a.html 页面想要得到的数据值 
    window.name = "hello world!";
</script>

7.location.hash

该方式跨域是因为子框架可以修改父框架 src 的 hash 值,通过这个属性进行传递数据,且更改 hash 值,页面不会刷新。但是传递的数据的字节数是有限的。

// 页面 http://www.test.cn/a.html 的代码:
<iframe src="http://test.cn/b.html" id="myIframe" onload="test()" style="display: none;">
<script>
    // 2. iframe载入 "http://test.cn/b.html 页面后会执行该函数
    function test() {
        // 3. 获取通过 http://test.cn/b.html 页面设置 hash 值
        var data = window.location.hash;
        console.log(data);
    }
</script>

// 页面 http://test.cn/b.html 的代码:
<script type="text/javascript">
    // 1. 设置父页面的 hash 值
    parent.location.hash = "world";
</script>

【注意】参考博客:https://www.cnblogs.com/itmacy/p/6958181.html

         https://blog.csdn.net/u014727260/article/details/72793459

                                 https://www.cnblogs.com/chiangchou/p/jsonp.html

                                 http://www.cnblogs.com/laixiangran/p/9064769.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值