美文网首页
跨源网络访问

跨源网络访问

作者: igor_d140 | 来源:发表于2018-09-17 22:09 被阅读31次

    链接:浏览器的同源策略
    链接:跨域资源共享
    链接:跨域共享数据的十种方法
    链接:前端跨域问题及其解决方案

    广义的跨域:
    1.) 资源跳转: A链接、重定向、表单提交
    2.) 资源嵌入: <link>、<script>、<img>、<frame>等dom标签,还有样式中background:url()、@font-face()等文件外链
    3.) 脚本请求: js发起的ajax请求、dom和js对象的跨域操作等

    跨源网络访问特点
    允许跨域写、资源嵌入 写:(链接links,重定向以及表单提交...)。内嵌资源(可读取嵌入图片的高度和宽度...)
    不允许跨域读
    可用于嵌入跨源的标签
    标签
    script跨域脚本 语法错误信息只能在同源脚本中捕捉到
    link css CSS跨域需要设置正确的Content-Type 消息头
    img 嵌入图片 图片格式包括PNG,JPEG,GIF,BMP,SVG,...
    videoaudio 多媒体资源
    objectembedapplet 插件
    @font-face 浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)
    frameiframe 可载入任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。
    ... ...
    跨域资源共享(cross-origin sharing)

    跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

    CORS
    方式 如:XMLHttpRequest、Fetchs使用CORS,以降低跨域HTTP请求所带来啊的风险
    限制 CORS需要客户端和服务端同时支持
    共享范围 XMLHttpRequest、Fetch发起的HTTP请求。Web字体@font-face。WebGL贴图。媒体资源画面绘制Images/video绘制到canvas。样式表。Scripts
    常见跨域方案
    方案
    JSONP跨域 jsonp是利用script标签可嵌入跨源的特性。嵌入的资源为js脚本(实际是动态对上文存在函数的实例化),仅支持get
    Flash URLLoader 通过flash发送HTTP请求(iOS不支持)
    cross-origin sharing(CORS) 服务端设置白名单Access-Control-Allow-Origin: [域名白名单],客户端通过XMLHTTPRequest /Fetch/XDomainRequest(IE8)请求
    server proxy nginx/nodejs/apache...代理
    document.domain + iframe 父子域,兄弟域场景。设置document.domain为同样值(或基础主域)
    location.hash + iframe FIM – Fragment Identitier Messaging a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信
    window.name + iframe name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)
    postMessage 页面与新窗口,多窗口之间,页面与iframe信息交互
    WebSocket协议跨域 浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现
    Flash LocalConnection SWF之间通过进程通信
    Cross Frame Cross Frame是FIM的一个变种,它借助了一个空白的iframe

    JSONP实际是动态对上文存在函数的实例化

    <script>
        function setTitle(title) {
          return title ?  document.querySelector('title').innerHTML = title : 0
        }
        function setName(name) {
          return name ?  document.getElementById('name').innerHTML = name : 0
        }
      ...
    </script>
      <script src="https://www.jianshu.com/...."></script> // 异步返回setTitle('跨源网络访问')  ,setName('可返回N多个')  ......
    
    
    document.domain + iframe 解决跨域
    1.)父窗口:(http://www.domain.com/a.html)<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
    <script>
        document.domain = 'domain.com';
        var user = 'admin';
    </script>复制代码2.)子窗口:(http://child.domain.com/b.html)<script>
        document.domain = 'domain.com';
        // 获取父窗口中变量
        alert('get js data from parent ---> ' + window.parent.user);
    </script>
    
    
    
    这种方式适用于主域相同,子域不同,比如http://www.a.com和http://b.a.com
    假如这两个域名下各有a.html 和b.html,
    
    a.html
    
        document.domain = "a.com";
        var iframe = document.createElement("iframe");
        iframe.src = "http://b.a.com/b.html";
        document.body.appendChild(iframe);
        iframe.onload = function() {
            console.log(iframe.contentWindow....); // 在这里操作b.html里的元素数据
        }
    
    b.html
    
        document.domain = "a.com";
    
    注意:document.domain需要设置成自身或更高一级的父域,且主域必须相同。
    
    

    postMessage

    postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:a.) 页面和其打开的新窗口的数据传递b.) 多窗口之间消息传递c.) 页面与嵌套的iframe消息传递d.) 上面三个场景的跨域数据传递用法:postMessage(data,origin)方法接受两个参数data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
    
    

    WebSocket协议跨域

    WebSocket协议跨域WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。1.)前端代码:<div>user input:<input type="text"></div>
    <script src="./socket.io.js"></script>
    <script>
    var socket = io('http://www.domain2.com:8080');
    
    // 连接成功处理
    socket.on('connect', function() {
        // 监听服务端消息
        socket.on('message', function(msg) {
            console.log('data from server: ---> ' + msg); 
        });
    
        // 监听服务端关闭
        socket.on('disconnect', function() { 
            console.log('Server socket has closed.'); 
        });
    });
    
    document.getElementsByTagName('input')[0].onblur = function() {
        socket.send(this.value);
    };
    </script>复制代码2.)Nodejs socket后台:var http = require('http');
    var socket = require('socket.io');
    
    // 启http服务
    var server = http.createServer(function(req, res) {
        res.writeHead(200, {
            'Content-type': 'text/html'
        });
        res.end();
    });
    
    server.listen('8080');
    console.log('Server is running at port 8080...');
    
    // 监听socket连接
    socket.listen(server).on('connection', function(client) {
        // 接收信息
        client.on('message', function(msg) {
            client.send('hello:' + msg);
            console.log('data from client: ---> ' + msg);
        });
    
        // 断开处理
        client.on('disconnect', function() {
            console.log('Client socket has closed.'); 
        });
    });
    




    跨源访问

    同源策略控制了不同源之间的交互,例如在使用XMLHttpRequest<img> 标签时则会受到同源策略的约束。这些交互通常分为三类:

    • 通常允许跨域写操作(Cross-origin writes)。例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 preflight
    • 通常允许跨域资源嵌入(Cross-origin embedding)。之后下面会举例说明。
    • 通常不允许跨域读操作(Cross-origin reads)。但常可以通过内嵌资源来巧妙的进行读取访问。例如可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法,或availability of an embedded resource.

    以下是可能嵌入跨源的资源的一些示例:

    • <script src="..."></script> 标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
    • <link rel="stylesheet" href="..."> 标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type 消息头。不同浏览器有不同的限制: IE, Firefox, Chrome, Safari (跳至CVE-2010-0051)部分 和 Opera
    • <img>嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,...
    • <video><audio>嵌入多媒体资源。
    • <object>, <embed>[<applet>](https://developer.mozilla.org/zh-CN/docs/HTML/Element/applet "HTML/Element/applet") 的插件。
    • [@font-face](https://developer.mozilla.org/zh-CN/docs/CSS/@font-face "CSS/@font-face") 引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。
    • <frame>[<iframe>](https://developer.mozilla.org/zh-CN/docs/HTML/Element/iframe "HTML/Element/iframe") 载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。
    跨源数据存储访问

    存储在浏览器中的数据,如localStorageIndexedDB,以源进行分割。每个源都拥有自己单独的存储空间,一个源中的Javascript脚本不能对属于其它源的数据进行读写操作。

    Cookies 使用不同的源定义方式。一个页面可以为本域和任何父域设置cookie,只要是父域不是公共后缀(public suffix)即可。Firefox 和 Chrome 使用 Public Suffix List 决定一个域是否是一个公共后缀(public suffix)。Internet Explorer使用其自己的内部方法来确定域是否是公共后缀。不管使用哪个协议(HTTP/HTTPS)或端口号,浏览器都允许给定的域以及其任何子域名(sub-domains) 访问 cookie。设置 cookie 时,你可以使用Domain,Path,Secure,和Http-Only标记来限定其访问性。读取 cookie 时,不会知晓它的出处。 即使您仅使用安全的https连接,您看到的任何cookie都可能使用不安全的连接进行设置。

    如何允许跨源访问

    使用 CORS 允许跨源访问。

    如何阻止跨源访问
    • 阻止跨域写操作,只要检测请求中的一个不可测的标记(CSRF token)即可,这个标记被称为Cross-Site Request Forgery (CSRF) 标记。必须使用这个标记来阻止页面的跨站读操作。
    • 阻止资源的跨站读取,需要保证该资源是不可嵌入的。阻止嵌入行为是必须的,因为嵌入资源通常向其暴露信息。
    • 阻止跨站嵌入,需要确保你的资源不能是以上列出的可嵌入资源格式。多数情况下浏览器都不会遵守 Conten-Type 消息头。例如,如果您在HTML文档中指定 <script> 标记,则浏览器将尝试将HTML解析为JavaScript。 当您的资源不是您网站的入口点时,您还可以使用CSRF令牌来防止嵌入。
    跨源脚本API访问

    avascript的APIs中,如 iframe.contentWindow, window.parent, window.openwindow.opener 允许文档间直接相互引用。当两个文档的源不同时,这些引用方式将对 WindowLocation对象的访问添加限制,如下两节所述。

    为了在不同源中文档进一步交流,可以使用window.postMessage

    Window

    规范: http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window.

    允许以下对 Window 属性的跨源访问:

    方法:

    window.blur
    window.close
    window.focus
    window.postMessage

    属性
    window.closed 只读.
    window.frames 只读.
    window.length 只读.
    window.location 读/写.
    window.opener 只读.
    window.parent 只读.
    window.self 只读.
    window.top 只读.
    window.window 只读.
    Location

    Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-location.

    允许以下对 Location 属性的跨源访问:
    location.replace
    URLUtils.href

    原文链接

    相关文章

      网友评论

          本文标题:跨源网络访问

          本文链接:https://www.haomeiwen.com/subject/xezdnftx.html