浏览器安全的基石是“同源政策”(same-origin policy)。

1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。

何为同源?

  • 协议相同
  • 域名相同
  • 端口相同

限制范围

  • Cookie、LocalStorage 和 IndexedDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求不能发送。

  PS:Form表单提交不受同源政策限制;

一级域名相同,二级域名不同网页Cookie 和 iframe规避同源政策

一级域名相同,只是二级域名不相同的2个网页(A页和B页)间通信(共享cookie和ifrmame DOM):

//A网页通过脚本设置一个 Cookie
document.cookie = "test1=hello"; //B网页不能读取
var allCookie = document.cookie; //父窗口不能读取子iframe的DOM对象,报错
document.getElementById("myIFrame").contentWindow.document //同样子窗口不能获取父窗口的元素,报错
window.parent.document.body

如果两个窗口一级域名相同,只是二级域名不同,那么设置document.domain属性,就可以规避同源政策,共享cookie和获取DOM,解决上面的问题:

//设置为一级域名,规避同源政策
document.domain = 'example.com';

完全不同源网站解决跨域窗口间通信问题

有2种方法:

  • 片段识别符(fragment identifier)
  • 跨文档通信API(Cross-document messaging)

片段识别符(fragment identifier),指的是URL的#号后面的部分,将此作为两个窗口通信内容的中介存储,可互为读取,实现通信。

父窗口把信息写入子窗口的片段识别符:

var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;

子窗口通过监听hashchange事件,得到通知:

window.onhashchange = checkMessage;

function checkMessage() {
var message = window.location.hash;
// ...
}

同样,子窗口也可以改变父窗口的片段识别符:

parent.location.href= target + “#” + hash;

上面两种方法都属于破解,HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging)。

这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源:

父窗口向子窗口发送消息:

var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

子窗口向父窗口发送消息:

window.opener.postMessage('Nice to see you', 'http://aaa.com');

postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即“协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。

父窗口或子窗口监听对方发来的消息:

window.addEventListener('message', function(e) {
console.log(e.data);
},false);

message事件的事件对象提供3个属性:

  • event.source:发送消息的窗口
  • event.origin: 消息发向的网址
  • event.data: 消息内容

子窗口通过event.source属性引用父窗口,然后回复消息:

window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
event.source.postMessage('Nice to see you!', '*');
}

event.origin属性可以过滤不是发给本窗口的消息:

window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
if (event.origin !== 'http://aaa.com') return;
if (event.data === 'Hello World') {
event.source.postMessage('Hello', event.origin);
} else {
console.log(event.data);
}
}

一个跨文档通信API案例:

//父窗口发送消息的代码
var win = document.getElementsByTagName('iframe')[].contentWindow;
var obj = { name: 'Jack' };
win.postMessage(JSON.stringify({key: 'storage', data: obj}), 'http://bbb.com'); //子窗口接收消息,写入localStorage
window.onmessage = function(e) {
if (e.origin !== 'http://bbb.com') {
return;
}
var payload = JSON.parse(e.data);
localStorage.setItem(payload.key, JSON.stringify(payload.data));
};

AJAX与同源政策

同源政策规定,AJAX请求只能发给同源的网址,否则就报错。

AJAX有3种方法规避同源政策:

  • JSONP
  • WebSocket
  • CORS

第1种:JSONP

JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据以一个指定名字的回调函数的参数形式传回客户端,客户端在约定名字的回调函数中处理接收到的参数 。

首先,网页动态插入<script>元素,由它向跨源网址发出请求。

function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
} window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
} function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};

服务器收到这个请求以后,会将数据放在回调函数的参数位置返回:

foo({
"ip": "8.8.8.8"
});

由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,所以不用JSON.parse处理,直接作为JSON对象使用。

参考

同源政策,阮一峰 http://javascript.ruanyifeng.com/bom/same-origin.html

浏览器-同源政策(same-origin policy)的更多相关文章

  1. 破解浏览器同源政策利器之JSONP

    本文是在了解了浏览器的同源规则之后,学习了破解这个规则的一个简单有效的方法->JSONP.主要通过阮一峰老师的博客学习 浏览器的同源规则 有这样一个背景,如果你通过银行的网站进行的取钱的交易,而 ...

  2. 前端开发必须说的那些事之——同源策略(same origin policy)

    同源策略指的是三个相同 协议相同 域名相同 端口相同 如https://www.baidu.com/hahah.html这个网址来说 https是使用的协议,www.baidu.com是域名,端口号默 ...

  3. 为什么ajax 必须同源,same origin policy

    ajax 所有请求都会附带主域的cookie, 若没有同源策略,攻击者就可以获取你的cookie,状态.

  4. Same Origin Policy 浏览器同源策略详解

    同源策略 Same Origin Policy 日常开发中最常与网络打交道,那关于浏览器的同源策略和跨域相关的知识是该整理一下了. 首先需要明确的是,同源策略是浏览器的安全策略,由于存在这个策略,我们 ...

  5. [js]浏览器同源策略(same-origin policy)

    浏览器的同源策略 浏览器同源政策及其规避方法 什么是同源策略 A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源".所谓"同源"指的是" ...

  6. 同源策略(same-origin policy)及三种跨域方法

    同源策略(same-origin policy)及三种跨域方法 1.同源策略 含义: 同源是指文档的来源相同,主要包括三个方面 协议 主机 载入文档的URL端口 所以同源策略就是指脚本只能读取和所属文 ...

  7. 浏览器同源策略,跨域请求jsonp

    浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...

  8. 浏览器同源策略与ajax跨域方法汇总

    原文 什么是同源策略 如果你进行过前端开发,肯定或多或少会听说过.接触过所谓的同源策略.那么什么是同源策略呢? 要了解同源策略,首先得理解“源”.在这个语境下,源(origin)其实就是指的URL.所 ...

  9. Ajax中的同源政策

    Ajax中的同源政策 Ajax请求限制 Ajax只能向自己的服务器发送请求.比如现在有一个A网站.有一个B网站,A网站中的HTML文件只能向A网站服务器中发送Ajax请求,B网站中的HTML文件只能向 ...

随机推荐

  1. Mac多SSH Key配置

    多SSH key配置 工作的时候碰到SSH配置的问题,就是公司用的是gittea的仓库,而本人的github平常也要使用,这个时候就需要配置不同的SSH key了.将同一个公钥分配配置给github和 ...

  2. Node.js 开发指南-读书笔记

    1. Node.js 使用了单 线程.非阻塞的事件编程模式 Node.js 最大的特点就是采用异步式 I/O 与事件驱动的架构设计.对于高并发的解决方 案,传统的架构是多线程模型,也就是为每个业务逻辑 ...

  3. java知识精要(一)

    一.java数组 (疯狂java讲义 第4.5 ~ 4.6章节) 1) 声明形式: type[] arrayName; 推荐方式 type arrayName[]; 2) 初始化: 方式一: type ...

  4. Dubbo使用javassist生成动态类

    在服务(本地和远程)暴露的时候会调用proxyFactory.getInvoker方法 具体位置: 本地暴露:ServiceConfig#exportLocal line:538 远程暴露: Serv ...

  5. Kafka 系列(一)—— Kafka 简介

    一.简介 ApacheKafka 是一个分布式的流处理平台.它具有以下特点: 支持消息的发布和订阅,类似于 RabbtMQ.ActiveMQ 等消息队列: 支持数据实时处理: 能保证消息的可靠性投递: ...

  6. 记一次 WPS Pro 2019 设备和驱动器图标删除

    1.图标预览 先看样式 2.软件不能关闭 百度和腾讯网盘都会创建,但是可以软件关闭,WPS以前也可以,现在新版作妖了 3.注册表删除 你做那我就删~Code:HKEY_CURRENT_USER\Sof ...

  7. linux搭建GitLab

    GitLab CentOS6 1. 安装VMware和CentOS 2. 安装必备Linux插件 3. 准备安装GitLab 4. 开始安装GitLab 5. 配置GitLab 6. 启动GitLab ...

  8. python爬虫-房天下-登录

    房天下-登录 本次爬取的网址为:https://passport.fang.com 一.分析请求 输入用户名和密码,点击登录按钮 请求的参数为: uid: 123456789 pwd: 64ccd42 ...

  9. PHP实现curl post和get

    CURL这里就不说明了.以下是简单案例 一.POST //初始化 $curl = curl_init(); //设置抓取的url curl_setopt($curl, CURLOPT_URL, 'ht ...

  10. php exec执行视频图片转换

    首先安装ffmpeg <?php set_time_limit(0) ; $cmd = "ffmpeg -i 'input/3.mp4' -r 1 -q:v 2 -f image2 i ...