美文网首页
跨源网络访问

跨源网络访问

作者: 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

原文链接

相关文章

  • 跨源访问网络

    跨源网络访问 同源策略控制了不同源之间的交互,例如在使用XMLHttpRequest或 标签时则会受到同源策略的约...

  • 跨源网络访问

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

  • 网络

    跨网 描述:比如联通网络用户访问移动网络的服务器,就等于跨网了。影响:跨网最明显的影响就是访问变慢 跨网结算 跨网...

  • 跨域

    什么是跨域 跨域指的是浏览器源文档访问另一个源文档。具体可以查看web同源策略 为什么要有跨域 跨域是出于浏览区安...

  • CORS(跨域资源共享-跨域访问)

    概述 出于安全原因,浏览器允许通过标签进行跨域访问(如img标签的src属性),但限制从脚本内发起的跨源访问(如A...

  • 第六周作业

    1、自建yum仓库,分别为网络源和本地源。本地源 网络源 2、编译安装http2.4,实现可以正常访问,并将编译步...

  • 第七周作业

    1、自建yum仓库,分别为网络源和本地源 配置网络源 配置本地源 2、编译安装http2.4,实现可以正常访问,并...

  • (十二)MySQL跨源访问Federated

    Federated引擎的使用 场景 两个数据源DB1和DB2,需要在DB1中访问DB2的表或视图,类似Oracle...

  • 安卓手机测试常见BUG

    安装 覆盖安装 跨版本安装 卸载后重新装 2、网络 2G网络下访问应用 网络不好的情况下,访问应用,是否会有数据返...

  • python 修改pip源

    python 修改pip源 ​ 由于网络原因,访问国外的pip源超级慢,因此可将源改为国内源(都是p...

网友评论

      本文标题:跨源网络访问

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