浏览器的同源策略与跨域

本文所有案例在本地址都可找到:https://github.com/dancingZhou/sameOrigin/tree/dev

什么是同源策略

两个页面地址中的协议、域名和端口号一致,则表示同源。

例如该地址 https://www.google.com 和以下地址对比

地址同源原因
http://www.google.com协议不一致
https://google.com域名不一致
https://www.google.com:81端口号不一致
https://www.google.com/a/s.html协议,域名和端口号都一致

同源策略的限制:

  1. 存储在浏览器中的数据,如localStroage、Cooke和IndexedDB不能通过脚本跨域访问

  2. 不能通过脚本操作不同域下的DOM

  3. 不能通过ajax请求不同域的数据

为什么要同源策略

设置同源限制主要是为了安全,如果没有同源限制存在浏览器中的Cookie等其他数据可以任意读取,不同域下DOM任意操作,Ajax任意请求的话如果浏览了恶意网站那么就会泄漏这些隐私数据。

Cookie一般用来保存登录状态。在登录一个银行网站后此时浏览器中就保存了登录的状态,同时浏览了恶意网站,这时Cookie的信息没有同源限制的话恶意网站就可以获取这些Cookie信息来达到不为人知的目的。

如果可以操作不同域下的DOM可以用如下方式完成盗取信息。在自己的网站上嵌入一个iframe地址设置成银行地址,然后让iframe全屏显示,当你一不小心上当了输入你账号密码,我就可以通过DOM操作获取到输入的信息。

Ajax的限制同Cookie,如果带上Cookie去跨域访问接口就可以通过程序的验证被认为身份是合法的。

既然瞥见危害一角自然要严加防范,限制非同源操作。

怎么规避同源策略

在看法一个网站的过程中有的数据并不在同一台服务器上这时怎么跨域调用就是一个很棘手的问题,可以通过以下几个方式来规避同源的限制。

DOM同源策略的规避

hash

因为hash的改变并不会引起页面的刷新同时可以通过 window.onhashchange事件监听到hash的改变,所以可以通过hash来跨域传递数据。

<!-- http://example.com/index.html -->
<html><head><meta charset="utf8"/><title>跨域DEMO --- hash</title></head><body><iframe id="iframe" src="http://example2.com/index.html"></iframe><script>var ifra = document.getElementById('iframe');ifra.onload = function(){// ifra 加载完成了ifra.src = ifra.src + '#data';}</script></body>
</html>
<!-- http://example2.com/index.html -->
<!-- 在iframe中的页面(example2.com)如果和iframe所在页面(example.com)不同域是不能获取所在页面的DOM,然后通过hash将数据传递回去的,也就是说如果同域就可以通过该方法向所在页面传递数据 -->
<html><head><meta charset="utf8"/><title>跨域DEMO --- hash</title></head><body><script>window.onhashchange = function(){// 打印通过hash传过来的数据console.log( location.hash ); }</script></body>
</html>

该方法会直接暴露所传递的数据并且对所传数据有大小限制。

document.domain

若两个文档的域相同则可以获取对方的DOM对象,并且可以通过设置 document.domain 的值来让两个文档的域保持一致,但是 document.domain 并不是可以设置任何值,只能设置为当前域的超域,比如:

m.example.com 设置为 example.com,并且不能 example.com 设置为 m.example.com 也不能将 m.example.com 设置为 example2.com。

所以document.domain只可以在拥有相同的主域名的不同子域名之间跨域。

<!--http://a.example.com-->
<html><head><meta charset="utf8"/><title>跨域DEMO --- document.domain</title></head><body><p id="data">我在 a.example.com 下</p><iframe id="ifra" src="http://b.example.com/index.html"></iframe><script>// 这里为什么也要设置呢?因为document.domain的赋值会导致端口被覆盖成null,并且js中没有手段单独设置端口,所以这里设置一遍这样就和iframe中的一致了。document.domain = 'example.com';var ifra = document.getElementById('ifra');ifra.onload = function(){console.log( ifra.contentWindow.document.getElementById('data').innerHTML ); // 我是b.example.com下的}</script></body>
</html>
<!--http://b.example.com-->
<html><head><meta charset="utf8"/><title>跨域DEMO --- document.domain</title></head><body><p id="data">我是b.example.com下的</p><script>document.domain = 'example.com';console.log( parent.document.getElementById('data').innerHTML ); // 我在 a.example.com 下</script></body>
</html>

window.name

window.name有一个特性,即使当前窗口的地址改变了window.name的值也不会改变。可以利用这一特性来进行跨域,步骤如下:

  1. 通过iframe加载需要获取数据的地址
  2. 在加载的文件上将数据设置到window.name上
  3. 数据获取完成后将iframe的地址设置为当前文档同域
  4. 通过DOM操作拿到window.name上的数据
<!--http://example.com-->
<html><head><meta charset="utf8"/><title>跨域DEMO --- window.name</title></head><body><iframe id="ifra" src="http://example2.com/index.html"></iframe><script>var retData = false;var ifra = document.getElementById('ifra');ifra.onload = function(){if( !retData ){ifra.src = 'http://example.com/index.html'retData = true;}else{console.log( ifra.contentWindow.name ); // 我在example2.com下}}</script></body>
</html>
<!--http://example2.com-->
<html><head><meta charset="utf8"/><title>跨域DEMO --- window.name</title></head><body><script>window.name = '我在example2.com下';</script></body>
</html>

window.postMessage

以上几种跨域的方法都属于破解行为,而postMessage是H5为跨域提供的解决方法。

otherWindow.postMessage(message, targetOrigin[, transfer])
<!--http://example.com-->
<html><head><meta charset="utf8"/><title>跨域DEMO --- window.postMessage</title></head><body><iframe id="ifra" src="http://example3.com/index.html"/><script>var ifra = document.getElementById('ifra');ifra.onload = function(){ifra.contentWindow.postMessage('我来自example.com', 'http://example3.com')}</script></body>
</html>
<!--http://example3.com-->
<html><head><meta charset="utf8"/><title>跨域DEMO --- window.postMessage</title></head><body><iframe src="http://example2.com/index.html"/><script>window.addEventListener('message', function(messageEvent){console.log( messageEvent.data ); // 我来自example.com}, false)</script></body>
</html>

messageEvent对象上的属性中有三个属性要注意,分别是:

  1. source 发送消息的窗体
  2. origin 发送消息的域名 (根据域名判断是否处理该消息)
  3. data 发送消息的内容 (获取发送的消息内容)

Ajax同源策略的规避

jsonp

虽然跨域限制了Ajax请求,但是却并不影响跨域引用脚本。

<script>function callback (data) {console.log(data); // 上面的加载完成之后就会打印出后台传过来的数据 "数据"}    
</script>
<script src="http://example.com/index.php?arg=val1&jsonp=callback"></script>
<?phpecho $_GET['jsonp'] . '(' . '数据' . ')';
?>

上面的 index.php 接口返回的是一段调用 函数的js代码 callback(data),其中data就是接口要返回的数据。而这个callback是事先在页面上写好的处理数据的回调函数,并且回调函数的名称通过URL参数的形式传递给了后端接口,这样就完成了一次跨域。

注:jsonp只支持GET请求。

CORS

cors(跨域资源共享)

参考

  1. https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
  2. https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
  3. http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

poj 1185

经典状态dp 代码&#xff1a; #include<iostream> #include<fstream> #include<cmath>using namespace std;int n,m;char map[101][11];int state[101][1024]; int num[101]; int value[1024]; int maxx;int ok(int s,int t){int i,j,k;for(i0;i<m;){jt&…

day03 爬虫

今日内容&#xff1a;一 爬虫原理二 Requests请求库一 爬虫原理1.什么是互联网&#xff1f;指的是由一堆网络设备&#xff0c;把一台台的计算机互联网到一起称之为互联网。2.互联网建立的目的&#xff1f;互联网建立的目的是为了数据的传递以及数据的共享。3.什么是数据&#x…

Java英雄:丹·艾伦

“ Java英雄 ”系列休息了很长时间。 老实说&#xff0c;我想即使有很多人想在这里收录&#xff0c;它也可能会以虚无收场。 其中之一是丹。 我第一次要求他捐款已经将近一年半了&#xff0c;与此同时发生的一切&#xff0c;让我不再有任何答案就让我安心了。 但是以下内容在Ja…

yearProgress.vue

1 <template>2 <div class"progressbar">3 <el-progress :text-inside"true" :soke-width"18" :percentage"percent" status"exception"></el-progress>4 <p>{{year}}年已经过去了…

group by rollup

首先引用ITPUB上的总结&#xff1a; rollup(a,b,c)----------------> 从右到底递减汇总>group by a,b,c (减0次)UNION ALL>group by a,b (减1次)UNION ALL>group by a (减2次)UNION ALL>group by null(全部汇总) (全部减掉)移动了4次&#xff0c;所…

Java-Class-I:java.util.List

ylbtech-Java-Class-I&#xff1a;java.util.List1.返回顶部 1.1、import java.util.ArrayList;import java.util.List; 1.2、List<Integer> newList new ArrayList<Integer>();newList.add(3); 2、 2.返回顶部1.1、import java.util.*;public class Test{public …

JS中编码的三种方法

在开发中经常需要对用户输入的数据进行编码然后才能通过HTTP请求发送给后台&#xff0c;或者对传递过来的数据进行解码。在JS中原生提供了三种编码/解码方式&#xff0c;分别是 encodeURI、 encodeURIComponent和 escape。 为什么URL需要编码&#xff1f; URI设计要求可移植&…

一个类加载的谜团解决了

面对一个好老问题 我在应用程序服务器上遇到一些类加载问题。 这些库被定义为Maven依赖项&#xff0c;因此被打包到WAR和EAR文件中。 不幸的是&#xff0c;其中一些也已安装到应用程序服务器中&#xff0c;但版本不同。 启动应用程序时&#xff0c;我们遇到了与这些类型的问题相…

vue 隐藏滚动条

element-ui隐藏组件scrollbar&#xff1a; <el-scrollbar style"height:100%"> </el-scrollbar>真正的隐藏滚动条代码在这里&#xff1a;.el-scrollbar__thumb {display: none;}.el-scrollbar__wrap {overflow-x: hidden;overflow-y: auto;}更多专业前端…

希望菜鸟通过博客园的记录和学习,成为一个可以能把自己想发实现的小程序员!...

我是一个学习电气自动化专业的毕业生&#xff0c;工作多年&#xff0c;接触过c语言、vb、单片机、PLC、linux&#xff0c;希望菜鸟通过博客园的记录和学习&#xff0c;成为一个可以能把自己想发实现的小程序员&#xff01; 生活和工作中有许多自己的表格和统计数据&#xff0c;…

获取DOM元素方法小结

在开发中不可避免的需要操作DOM&#xff0c;现在就来总结一下原生的获取DOM的API。 getElementById() 该方法是最常用的通过元素的id属性来获取DOM元素的API&#xff0c;返回一个DOM元素。 <body><div id"div">我是div</div><script type&qu…

推荐:个人时间跟踪工具 ManicTime

在《个人管理 &#xff0d; 目标管理之前&#xff0c;你会时间管理吗》中我介绍的时间管理三阶段之一“对时间的实际去处进行记录”时说过现在有很多时间管理工具&#xff0c;也有人希望我介绍一下我使用的工具&#xff0c;那么我就利用中午休息时间&#xff0c;马上给大家介绍…

Java和甜蜜的科学

当您使用Java进行开发已有15年并且同事要求您帮助他们调试空指针异常时&#xff0c;您不会感到惊讶。 通常&#xff0c;很明显什么是null&#xff0c;唯一要做的就是找出原因。 有时会有些困难&#xff0c;因为有人创建了一系列取消引用的对象。 前几天&#xff0c;我遇到了一…

SQL Server 2005怎样进行性能排错

很少会有偶然的性能下降。设计不良的数据库或工作负载配置不正确的系统会经常导致性能问题。管理员需要能预先阻止或最小化问题的影响&#xff0c;当管理员遇到问题时&#xff0c;应该诊断问题并采取正确操作来修复问题。本文提供了按部就班的指导&#xff0c;通过使用可用的工…

AcWing 207. 球形空间产生器 (高斯消元)打卡

有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。 现在&#xff0c;你被困在了这个n维球体中&#xff0c;你只知道球面上n1个点的坐标&#xff0c;你需要以最快的速度确定这个n维球体的球心坐标&#xff0c;以便于摧毁这个球形空间产生器。 输入格式 第一行是一个整数…

jQuery中的ready

基于jQuery v1.8.3 在js与DOM交互之前要确保DOM已经加载构建完成&#xff0c;在jQuery中都是使用 (fn)或者(document).ready(fn)来确保自己写的代码在DOM构建完成之后执行。 那么jQuery的ready事件内部怎么实现的呢&#xff1f; 通过阅读源码&#xff08;line:842 ~ 898&…

JVM PermGen –您在哪里?

这篇文章介绍了JVM内存结构的一些基础知识&#xff0c;并快速窥视了PermGen&#xff0c;以了解自Java SE 8出现以来它已消失的地方。 裸基础 JVM只是系统上运行的另一个进程&#xff0c;魔术始于java命令。 像任何OS进程一样&#xff0c;它需要内存才能运行。 记住– JVM本身是…

vue 开发过程中遇到的问题

1. gitlab团队协作开发 2. element ui 问题集锦 3. 使用vue和ElementUI快速开发后台管理系统 更多专业前端知识&#xff0c;请上 【猿2048】www.mk2048.com

python6-函数

转载于:https://www.cnblogs.com/WIU1905/p/11101249.html

Windows Phone 7.1 “芒果” SDK Beta 下载地址

Windows Phone 7.1 “芒果” SDK Beta 今天早上发布&#xff0c;第一时间下载体验。功能果然激动人心。 下载地址&#xff1a; 离线ISO请点我&#xff0c; 在线安装请点我。转载于:https://www.cnblogs.com/finehappy/archive/2011/05/25/2056849.html