前言

浏览器同源政策(Same-origin policy) 是浏览器安全的基石。它是前端开发人员必须要理解的一个知识点,也是后面各种实现跨域资源访问方式学习的基础。在接触这方面的知识时个人思考很多,在此记录一下。只能看作是个人的当前理解,并不代表一定准确,如果有误,希望指出。

1. 同源的定义

学习同源政策之前我们先明确一下同源的概念。在浏览器中,如果两个页面(请求)拥有相同的协议、域名和端口,那么这两个页面就属于同一个源(origin)。其中只要有其中一个不相同,就是不同源。例如网址 http://www.tkop.com/dirname/home 与下列各网址的同源关系分析如下。

  1. http://www.tkop.com/dirname3/admin (同源)
  2. http://www.yangchen.com/dirname/home (不同源,域名不相同)
  3. http://v1.www.tkop.com/dirname/home (不同源,域名不相同)
  4. http://www.tkop.com:81/dirname/home (不同源,端口号不相同)
  5. https://www.tkop.com/dirname/home (不同源,通信协议不同)

2. 同源政策对 ajax 请求的限制

同源政策由 Netscape 公司于 1995 年提出,其目的是为了保证用户信息的安全,防止恶意网站窃取数据。最初的同源政策是指 A 网站在客户端设置的 Cookie 在 B 网站(非同源页面)不能访问。

但是随着互联网的发展,同源政策也越来越严格(限制越来越多)。其中还规定了在不同源的情况下,无法向非同源地址发送 ajax 请求(ajax 请求限制),如果发请求,浏览器就会报错。通俗地讲就是 ajax 只能向自己地服务器发送请求。例如现有 A、B 两网站(服务器),A 网站中的页面只能向 A 服务器发送 ajax 请求,B 网站中的页面只能向 B 服务器发送 ajax 请求。但是浏览器是不允许 A 网站中的页面向 B 服务器发送 ajax 请求的(其实是允许的,不过拒绝接受处理响应),同理,也不允许 B 网站中的页面向 A 服务器发送 ajax 请求。 以上都是理论,下面我演示一下同源政策的 ajax 限制。

1、首先服务器端创建两个监听不同端口的服务。注意 A 监听 3000 端口,B 监听 3001 端口,两个服务不同源。

// 引入express框架
const express = require('express');
// 引入路径处理模块
const path = require('path');// 创建 A、B 两个服务
const A = express();
const B = express();
// 开放两服务器的静态文件
A.use(express.static(path.join(__dirname, 'publicA')));
// 虽然只是演示,但为让大家不搞混淆还是将静态文件放到两个不同的文件夹
B.use(express.static(path.join(__dirname, 'publicB')));// B服务的一个get请求处理路由
B.get('/example', (req, res) => {res.send('来自B的响应');
});// 分别监听不同端口(不同源)
A.listen(3000);
B.listen(3001);
console.log('服务已开启,需访问A、B服务器可访问本机不同端口');

2、创建服务器端服务后在 A 服务页面 aaa.html 中向 B 服务器发送 ajax 请求。这里为了方便没有使用 jquery 的 $.ajax() 发送请求或者原生 js 发送请求,而是使用了前面自己封装的 ajax() 函数。


3、访问地址 http://localhost:3000/aaa.html ,即访问 A 浏览器的静态页面。再向 B 浏览器发送 ajax 请求,查看浏览器对请求的处理和响应的处理。可以看到浏览器首先会出现如下报错信息。


使用我蹩脚的英语水平翻译过来就是:请求资源头信息中不存在 “Access-Control-Allow-Origin” 字段信息。从源 “http://localhost:3000” 访问 “http://localhost:3001” 的 ajax 请求已被同源政策阻止。

看看这次请求的请求头信息和响应头信息,如下图所示:


为了对比我们可以在 B 网站的 bbb.html 页面中发送一个相同的 ajax 请求(没有跨域),我将它的请求信息截图如下,方便与上图对比:


通过上图,比较一下跨域和不跨域的情况下请求报文和响应报文中头信息的一些字段的值的差异。

  • 跨域请求的请求头信息中的 Sec-Fetch-Site: same-site ,而非跨域请求的请求头信息中的 Sec-Fetch-Site: same-origin 。所以这是表示这次请求是否属于跨域请求。

  • 在跨域请求的请求头信息中则增加了 Origin 字段,值为发出请求的页面(aaa 的脚本)的协议、地址和端口

  • 然后比较一下响应头信息,发现它们一模一样,其实这算是同源政策的本质的一个体现。同源政策本质上是浏览器客户端为维护用户数据安全而设定的,与服务器端没有太大的联系(个人觉得唯一联系可能就是服务器可以提供是否允许跨域请求数据或者访问 cookie 等权限的验证信息供浏览器进行验证),这也是为什么我们将其称为浏览器的同源政策即无论是否涉及跨域,浏览器按照要求正常发出请求,服务器接收请求并给出响应,浏览器也能接收到响应。但是浏览器根据同源政策有权决定是否将响应数交由页面脚本处理(或者报错)

  • 为什么我敢给出上面的结论呢?你可以将注意力放在响应头信息中的 Content-Length 字段。这个字段显示的正是服务器响应内容的字节长度,例如上面的响应是字符串 “来自B的响应”,英文字母 B 是 1 个字节,每个汉字 3 个字节。这也就说明了即使跨域访问也确实可以接收到服务器的响应信息。

上面我们已经清楚了同源政策对 ajax 的限制,但是浏览器的同源政策的限制不止这个。总结如下:

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

在此我的笔记只会涉及 Cookie 无法获取和 ajax 请求无法发送的问题,其他的不会进行学习记录。不知道你是否已经了解学习过有关 Cookie 和 Session 的相关知识,都学到跨域资源共享了我觉得应该是没问题了。

3. 小对话(sessions)

为了更加深刻地理解浏览器地同源政策,我自己参考自己地思考编了下面一小段会话。A 代表 A 服务器,B 代表 B 服务器,aaa 代表上面的 aaa.html 页面(A 服务器的页面),bbb 代表 B 服务器上的 bbb.html 页面(B服务器上的页面,假设是登录页面),小刘代表浏览器。并假设 B 是我现在使用的 CSND 服务器,A 是某恶意网站。

用户在浏览器输入 B 网站首页地址。。。

用户:小刘你去跟 B 要一下它们首页的数据。

小刘跟 B 要了数据并将登录(bbb)页面渲染展示给用户。。。用户输入登录信息。。。

用户:登录账号密码填好了,小刘你让 B 瞧瞧看看我能不能登录。

B 验证用户输入的账号密码。。。确认通过。。。

B:小刘你跟用户说他登录成功了(响应数据),还有这是他的登录证明(Cookie),保存好,下次他跟我要东西(发请求)的时候带上它。我是记不住他的。

用户没有退出登录,又在浏览器输入A 网站的访问地址并请求到了 aaa 页面。。。

如果没有同源政策 aaa(其中添加的恶意脚本)可以怎么样?

aaa:小刘你去跟 B 要一下用户的用户的电话号码。

小刘此时并未察觉 aaa 不是 B 网站的页面脚本。小刘没管那么多就带着 B 给 Cookie 跟 B 要用户的电话号码。。。

小刘:B 哥这是你上次给用户的登陆证,他现在要看看电话号码,你给我吧。

B 看了看 Cookie 确实是自己发出去的,并根据 Cookie 里面的信息比如用户 ID 找到了用户的号码,并将它给了小刘。

小刘:aaa 这是你要的东西,不用谢。
aaa:小刘你再去跟 B 说我要删掉所有的博客内容并注销账户。

小刘此时还是未察觉 aaa 不是 B 网站的页面脚本,又带着 Cookie 过去了

B:什么!!!他要注销?好吧,登录证明(Cookie)你都带过来那证明他确实登录过了也有权进行这些操作了,那注销掉吧。

看到这我们发现如果没有同源政策会出现两个问题:

  • 浏览器不会根据是否同源去判断是否携带 B 给用户设置的 Cookie 来对 B 进行访问(或者说判断 aaa 是否有权访问使用这份 Cookie),导致服务器误判。
  • 浏览器也不会根据是否同源判断脚本是否有权力获得服务器响应的数据。

根据这两点我们大概也就理解了同源政策的本质。如果有同源政策那上面的对话会变成怎么样呢?

aaa:小刘你去跟 B 要一下用户的用户的电话号码。

小刘看了看 aaa 的请求地址中的协议、IP 和端口。嗯?发现它和 B 不是同源的,也不知 B 哥允许它请求数据不。将它记在笔记本(Origin)上先。但是 B 哥上次给的登录证(Cookie)就默认不带了。

小刘:B 哥有个哥们想向你要电话号码。

B 看看小刘没带登录证说明他那哥们没登陆过呀,给你返回些没登录过的数据吧(叫他先登录)。

B:小刘这是你可以给他的数据,还有这是能够得到这些数据的白名单(Access-Control-Allow-Origin),还有这是我能接受他们(白名单内的人)的请求方式(Access-Control-Allow-Methods),如果他们在名单内就给他们数据吧,你自己决定。

小刘拿到哪份名单发现 aaa 的 IP 和协议虽然一样但是端口不一样。。。。当然 B 哥也许没有给他那份名单(例如我们的示例),那连给都没给说明不允许跨域了。

小刘:aaa 对不起呀,B 并不允许你获取他的数据。他提供的数据我不能给你(报错)。

上面的某些内容涉及到了跨域资源共享的部分知识和有关跨域 Cookie 携带问题。后面会详细介绍(相关笔记写完贴链接)。反正上面就大致体现出了同源策略的重要性,并不是说他可以解决掉所有问题,使网站绝对安全(谁都做不到,不知道你有没有看过没有绝对安全的系统这个电影),例如恶意网页可以伪造Origin头信息,绕过服务端对Origin头的检查等。

下面是我在一个有关文章下面看到的一个有关评论,觉得不错所以截了下来。


以上就是我对浏览器同源政策的理解,如果对你有帮助希望可以给我点个赞(鼓励一下不断进行知识输出的人儿)。后面解决一下跨域资源访问的问题,涉及的知识有 JSONP、CORS 和 WebSocket

同源政策(same-origin policy)相关推荐

  1. 前端基础技术_浏览器同源政策(same-origin policy)及其规避方法

    目的:对浏览器的"同源策略"和"同源异构策略(跨域)"有个初步认识. 同源策略:此策略是浏览器和后台通讯之间的一个安全协议的支持,同源指两个网址的协议.域名(或 ...

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

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

  3. frame跨页传值/AJAX出错解决方案 + 知识补充:浏览器同源政策

    一.同源政策 1.1概念 浏览器安全的基石是 "同源政策"(same-origin policy). 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实 ...

  4. 浏览器同源政策及其规避方法

    浏览器安全的基石是"同源政策"(same-origin policy).很多开发者都知道这一点,但了解得不全面. 本文详细介绍"同源政策"的各个方面,以及如何规 ...

  5. 浏览器同源政策之ajax请求不能发送

    同源政策(same-origin policy)是浏览器安全的基石 同源指的是三个相同 限制范围 (1) Cookie.LocalStorage 和 IndexDB 无法读取.(2) DOM 无法获得 ...

  6. 01-浏览器同源政策 以及 什么是跨域?怎么解决跨域问题?

    1,为什么会有跨域问题? 我以前写代码,都没有遇到过跨域问题?突然遇到跨域问题了?很纳闷为啥要有跨域这个问题啊?我不跨域不好吗?这样我一个网站只要有超链接我可以一直点下去,比如友情链接,多好啊? 2. ...

  7. 学习-浏览器的同源政策

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

  8. AppStore 隐私政策(Privacy policy)

    AppStore 隐私政策(Privacy policy) 隐私政策说明 一.本公司如何收集您的个人信息 二.本公司如何使用您的个人信息 三.个人信息安全 四.本公司会将个人信息保存多久 五.法律免责 ...

  9. 同源策略(same origin policy)

    浏览器的同源策略 同源策略是一个重要的安全策略,它用于限制一个origin的文档或它加载的脚本如何能与另一个源的资源进行交互.能够减少恶意文档,减少可能被攻击媒介. 如果两个URL的协议.域名.端口号 ...

最新文章

  1. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记20 Multiple MVCs 多MVC模式、NavigationController导航控制器...
  2. 美团社招Java开发一面,二面,三面,四面合并面经
  3. 哈夫曼树--链式结构(建立huffman树、编码、解码)
  4. 网站推广专员浅析网站建设实用技巧助力网站推广优化
  5. Objective-C 内存管理机制
  6. Python 框架 之 Scrapy 爬虫(一)
  7. SpringBoot使用CommandLineRunner和ApplicationRunner执行初始化业务
  8. 2017.7.18 树上距离=k 思考记录
  9. eclipse的workspace和working set
  10. 2020教师计算机考试笔试题,2020年全国教师资格考试信息技术学科知识与能力练习题...
  11. 什么是 SNMP 和 MIB什么是 SNMP 和 MIB
  12. C站能力认证(C4前端基础认证) //任务二:根据浮动布局以及定位布局的特性,实现构建下列(截图)中的页面
  13. php CI框架单元测试
  14. shell判断大于、小于、等于
  15. IDEA报错:Failed to obtain JDBC ConnectionCannot create PoolableConnectionFactory
  16. 毕业设计:新闻大数据搜索系统 (完整代码运行)
  17. C/C++ 无法解析的外部符号解决方案
  18. redission使用案例
  19. 楚留香服务器维护,【楚留香】4月20日维护公告
  20. 算法题:一个圆环上有100个灯泡,灯泡有打开和关闭两种状态,灯泡的状态随机,按一个灯泡的开关,相邻的两个灯泡的状态也发生一次变化。比如暗-亮-暗,按中间灯泡,变化为亮-暗-亮。问设计一道算法,使得所有

热门文章

  1. 达达外卖对接php,达达配送教程
  2. tf.shape和tf.less
  3. 人生不会是场戏的^_^
  4. 移动开发技术(Android)——实验2 Android布局管理器的应用
  5. android是苹果手机吗,技术角度分析:这就是苹果手机和安卓手机为什么有差距的主要原因...
  6. 安装虚拟机哦-20200518
  7. Manifest merger failed : android:exported needs to be explicitly specified for element
  8. linux上mysql5.7忘记密码,Linux下Mysql5.7忘记密码
  9. 纯CSS3做3D动画魔方
  10. 怎么查询物流信息发货后是否揽收