ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

跨源通信

2021-05-06 13:52:37  阅读:192  来源: 互联网

标签:postMessage cn script color 跨源 通信 window


跨源通信的几种方式 1.JSONP 2.iframe*** 3.window.postMessage() 4.XMLHttpRequest level 2

跨源限制
在浏览器里
对源(url协议,主机名,端口号)不同的通信进行限制,在web领域 为了确保安全,只有同源的通信才能被允许进行,称为同源策略
虽然可以在html里使用iframe以实现在一个页面中同时显示来自不同域的文档,不过js仍然只能访问同一源的文档
如果文档的url和iframe的不同,则无法通过文档中包含的js对iframe内的dom进行操作,而iframe内的js也无法操作文档里的dom
如果不这样 ,就会发生诸如不同域的cookie能够互相访问等安全问题

对于XMLHttpRequest来说,同源策略的含义是,一个XMLHttpRequest对象只能发送至一个特定的服务器,即提供了使用该XMLHttpRequest对象的文档下载服务器
跨源通信

 

js里的跨源通信
JSONP
iframe***
window.postMessage()
XMLHttpRequest level 2

1.JSONP
利用script标签的src将其它域的js文件载入,如果在此处动态创建script标签的话,就能实现对其它域中数据的动态读取
不过仅仅是取得了数据,还无法在客户端使用。因此产生jsonp(json with padding ,padding指向json数据中添加函数名)
服务端会对数据添加函数名后返回
代码示例

 

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>title>
    <script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js">script>head><body><script>var url="http://b.cn/do.php?callback=foo";//注意 foo函数的定义要先于 引入 url里的内容function foo(res){
    console.log(res);
    console.log(res.a);
}function loadData(url){    var elem=document.createElement('script');
    elem.src=url;
    document.getElementsByTagName('head')[0].appendChild(elem);

}
loadData(url);script>body>html>

b.cn/do.php

<?php$arr=['a'=>'ajax','b'=>'bbc'];$callback=$_GET['callback'];$json=$callback."(".json_encode($arr).");";echo $json;   //foo({"a":"ajax","b":"bbc"});?>

请求的内容是执行代码的内容,在客户端是定义声明部分
jsonp的缺点
无法在post请求类型中使用
只能做到动态创建script标签并读取数据而无法从客户端发出数据

2. XMLHttpRequest level 2
XMLHttpRequest无法跨源通信
在XMLHttpRequest level2中 只要服务器端许可就可以实现

a.cn/a.html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>title>
    <script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js">script>head><body><div class="btn" style="cursor: pointer;text-align:center;width: 100px;height: 50px;line-height:50px;color:white;background: green">clickdiv><script>$(function(){
    $(".btn").click(function(){        var xhr=new XMLHttpRequest();
        xhr.onreadystatechange=function(){            var state=xhr.readyState;            if(state==4){
                console.log(xhr.getAllResponseHeaders());
            }
        }
        xhr.open('GET','http://b.cn/do.php?a=1&b=2');
        xhr.withCredentials=true; 
        //默认不发送cookie的,当设个参数设置为true服务端 Access-Control-Allow-Origin 必须明确指定 不可为* 而且必须设置 header('Access-Control-Allow-Credentials:true');        xhr.setRequestHeader("content-type",'multipart/form-data');//      xhr.setRequestHeader("content-type",'application/x-www-form-urlencoded');        xhr.send('p1=1');

    });

});script>body>html>
http://b.cn/do.php
代码
<?phpheader('Access-Control-Allow-Origin:http://a.cn');header('Access-Control-Allow-Credentials:true');header('Access-Control-Allow-Methods:POST');var_dump($_POST);var_dump($_GET);var_dump(file_get_contents("php://input"));var_dump($_COOKIE);

 关于跨源发送cookie 

xhr.withCredentials=true; 

这里跨源指的是 跨的二级的域,根域必须相同,而且cookie的域必须是根域 

比如 a.a.cn可以通过这里所说的跨源 在向b.a.cn发送ajax请求时 带上 .a.cn下的cookie

不要以为 域在.a.cn下的cookie ,a.a.cn在向b.a.cn发请求时 会自动带上

也不要认为cookie的跨源能跨根域,是不可能的


3.postMessage()

window.postMessage 是一个安全的跨源通信的方法。一般情况下,当且仅当执行脚本的页面使用相同的协议(通常都是 http)、相同的端口(http默认使用80端口)和相同的 host(两个页面的document.domain 的值相同)时,才允许不同页面上的脚本互相访问。 window.postMessage 提供了一个可控的机制来安全地绕过这一限制,当其在正确使用的情况下。


调用 window.postMessage时,将分发一个MessageEvent事件到目标窗口, 在所有挂起必须执行的脚本完成后.  (例如:当一个事件处理程序调用window.postMessage时,仍剩余事件处理程序,  先前的挂起等待超时等)。MessageEvent 有消息类型,它被设置为第一个参数值提供给window.postMessage的data属性, 对应的window调用window.postMessage的时候,window.postMessage主文档的来源的origin属性被称为源属性,指哪个调用window.postMessage的窗口。 (事件的其他标准属性都存在与对应的预期值。)


语法

otherWindow.postMessage(message, targetOrigin);

  • otherWindow
  • 其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames
  • message
  • 将要发送到其他 window的数据,将会被结构化克隆算法序列化。这意味着你可不受什么限制的安全传送数据对象给目标窗口而无需自己序列化
  • targetOrigin
  • 通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的orign属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
a.cn/a.html
<!DOCTYPE html><html><head>
    <title>Post Messagetitle>head><body><div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">
    <div id="color">Frame Colordiv>div><div>
    <iframe id="child" src="http://b.cn/b.html">iframe>div><script type="text/javascript">
    window.onload=function(){
        window.frames[0].postMessage('getcolor','http://b.cn');
    }

    window.addEventListener('message',function(e){
        console.log('a:',e);        var color=e.data;
        document.getElementById('color').style.backgroundColor=color;
    },false);script>body>html>

b.cn/b.html

<!doctype html><html><head>
    <style type="text/css">
        html,body{
            height:100%;
            margin:0px;
        }
    style>head><body style="height:100%;"><div id="container" onclick="changeColor();" style="widht:100%; height:100%; background-color:rgb(204, 102, 0);">
    click to change colordiv><script type="text/javascript">
    var container=document.getElementById('container');

    window.addEventListener('message',function(e){        if(e.source!=window.parent) return;        var color=container.style.backgroundColor;
        window.parent.postMessage(color,'*');
    },false);    function changeColor () {        var color=container.style.backgroundColor;        if(color=='rgb(204, 102, 0)'){
            color='rgb(204, 204, 0)';
        }else{
            color='rgb(204,102,0)';
        }
        container.style.backgroundColor=color;
        window.parent.postMessage(color,'*');
    }script>body>html>

  

标签:postMessage,cn,script,color,跨源,通信,window
来源: https://blog.51cto.com/huangkui/2756478

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有