zoukankan      html  css  js  c++  java
  • 跨域--什么是跨域?以及跨域的常用解决方案

    我们通常所说的跨域,就是指被同源策略限制了的请求场景。

    什么是同源策略?
    同源策略/SOP(Same origin policy)是一种约定,所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

    常用解决方案

    jsonp

    通过动态生成script,设置src为请求的跨域地址,并在其中拼接回调函数。跨域地址收到请求后,返回一个对该回调函数的调用。从而达到数据通信的实现。
    缺点:只支持get请求。

    CORS

    对于普通请求,只需服务端设置Access-Control-Allow-Origin即可;如果需要携带cookie,则前端需要设置withCredentials

    postMessage

    postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
    a.) 页面和其打开的新窗口的数据传递
    b.) 多窗口之间消息传递
    c.) 页面与嵌套的iframe消息传递
    d.) 上面三个场景的跨域数据传递

    语法: otherWindow.postMessage(message, targetOrigin, [transfer]);
    message: 传输的数据等
    otherWindow: 一个目标窗口的引用
    a.) 通过window.open()返回值
    b.) 通过iframe的contentWindow属性
    targetOrigin: 用来标识哪些窗口可以接受到消息。可以通过'*'配置为任何窗口。但为了安全性考虑,最好进行精准设置一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。
    transfer: 是一串和message一起传递的数据,但是所有权会转到目标窗口。

    用法如下:

    var bWindow = window.open(...b details...)
    var data = {name : 'ashen' ,age : 20}
    bWindow.postMessage(data, 'http://b.org')
    

    在bWindow中

    window.addEventListener('message', receiveMessage, false)
    function receiveMessage(event)
    {
      // 我们能信任信息来源吗?
      if (event.origin !== "http://example.com:8080")
        return;
    
      // event.source 就当前的来源页面
      // event.data 是 "{name : 'ashen' ,age : 20}"
    
      // 假设你已经验证了所受到信息的origin (任何时候你都应该这样做), 一个很方便的方式就是把event.source
      // 作为回信的对象,并且把event.origin作为targetOrigin
      event.source.postMessage("hi there yourself!  the secret response " +
                               "is: rheeeeet!",
                               event.origin);
    }
    
    

    nginx代理

    配置代理服务器,在前端看来并非跨域
    主要通过设置proxy_pass属性,为跨域地址

    WebSocket协议跨域

    websocket实现客户端和服务端的全双工通信,支持跨域

    document.domain + iframe跨域

    通过window.domain设置页面的基础主域相同
    只能处理主域相同子域不同的情况

    location.hash + iframe

    例如需要实现A域的a.html到B域的b.html的跨域。则需要借助同为A域的c.html页面。利用hash值可单向传递的特性实现,如下:

    // a.html
    <iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
    <script>
            setTimeout(function(){
                iframe.src = iframe.src + '#user=admin'
            }, 1000)
    
            function onCallback(res){
                alert('data from c.html ---->' + res)
            }
    </script>
    
    <iframe src="http://www.domain1.com/c.html" style="display: none;"></iframe>
    <script>
            window.onhashchange = function(){
                iframe.src = iframe.src + location.hash
            }
    </script>
    
    <iframe src="http://www.domain2.com/c.html" style="display: none"></iframe>
    <script>
          window.onhashchange = function () {
            window.parent.parent.onCallback(
              "hello" + location.hash.replace("#user=", "")
            );
          };
    </script>
    
  • 相关阅读:
    316 Remove Duplicate Letters 去除重复字母
    315 Count of Smaller Numbers After Self 计算右侧小于当前元素的个数
    313 Super Ugly Number 超级丑数
    312 Burst Balloons 戳气球
    309 Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期
    Java 类成员的初始化顺序
    JavaScript 全局
    HTML字符实体
    Java中的toString()方法
    JavaScript 弹窗
  • 原文地址:https://www.cnblogs.com/ashen1999/p/13839978.html
Copyright © 2011-2022 走看看