【每天学习一点新知识】浏览器的同源策略

目录

同源的定义 

同源策略的限制

规避同源策略

document.domain属性

跨域资源共享(CORS)

跨文档通信

JSONP

WebSocket

Nginx反向代理


        浏览器默认两个相同的源之间是可以相互访问资源和操作 DOM 的。两个不同的源之间若想要相互访问资源或者操作DOM,那么会有⼀套基础的安全策略的制约,我们把这称为 同源策略   

        同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。它的存在可以保护用户隐私信息,防止身份伪造等(读取Cookie)。

同源的定义 

一个域名地址由 协议、域名、端口、请求资源地址 等部分组成。

如果两个 URL 的协议、域名和端口都相同,我们就称这两个 URL 同源即便两个不同的域名指向同一个 ip 地址,也非同源。

下表给出了与 URL http://store.company.com/dir/page.html 的源进行对比的示例: 

URL结论原因
http://store.company.com/dir2/other.html同源只有路径不同
http://store.company.com/dir/inner/another.html同源只有路径不同
https://store.company.com/secure.html不同源协议不同
http://store.company.com:81/dir/etc.html不同源端口不同 ( http:// 默认端口是 80)
http://news.company.com/dir/other.html不同源主机不同

同源策略的限制

浏览器的同源策略目的是为了保护用户的信息安全,为了防止恶意网站窃取用户在浏览器上的数据,如果不是同源的站点,将不能进行如下操作 :

  • Cookie、LocalStorage 和 IndexDB 无法读写

        用户登录某个站点,站点后端服务器验证账号密码正确之后,会返回Cookie、Token 或者是用户名和密码给客户端浏览器,浏览器会将这些个人数据保存到Cookie、Session Storage、Local Storage、Cache、Indexed DB其中的一个(具体怎么保存,取决网站开发人员),如果浏览器没有同源策略,当用户访问恶意网站时,恶意网站就可以通过脚本获取用户的数据,这是极其不安全的行为。

        所以在不是同源的情况下,不能读写其他站点设置的Cookie、Session Storage、Local Storage、Cache、Indexed DB。

  • DOM 和 Js对象无法获得

        DOM 是 Document Object Model(文档对象模型)的缩写。

        来自一个源的js只能读写自己源的DOM树不能读取其他源的DOM树。

  • AJAX请求不能发送

        Ajax 全称“Asynchronous JavaScript and XML”,译为“异步 JavaScript 和 XML”。通过 Ajax 可以异步从服务器请求数据并将数据更新到网页中,整个过程不需要重载(刷新)整个网页,可以将网页的内容更快的呈现给用户。

        一般而言来自一个源的js只能向自己源的接口发送请求,不能向其他源的接口发送请求。当然其实本质是,一方面浏览器发现一个源的js向其他源的接口发送请求时会自动带上Origin头标识来自的源,让服务器能通过Origin判断要不要向应;另一方面,浏览器在接收到响应后如果没有发现Access-Control-Allow-Origin允许发送请求的域进行请求那也不允许解析。

规避同源策略

在某些情况下同源策略太严格了,给拥有多个子域的大型网站带来问题。下面就是解决这种问题的技术:

document.domain属性

        如果两个window或者frames包含的脚本可以把domain设置成一样的值,那么就可以规避同源策略,每个window之间可以互相沟通。例如,orders.example.com下页面的脚本和catalog.example.com下页面的脚本可以设置他们的document.domain属性为example.com,从而让这两个站点下面的文档看起来像在同源下,然后就可以让每个文档读取另一个文档的属性。这种方式也不是一直都有用,因为端口号是在内部保存的,有可能被保存成null。换句话说,example.com的端口号80,在我们更新document.domain属性的时候可能会变成null。

跨域资源共享(CORS)

        这种方式使用了一个新的Origin请求头和一个新的Access-Control-Allow-Origin响应头扩展了HTTP。允许服务端设置Access-Control-Allow-Origin头标识哪些站点可以请求文件,或者设置Access-Control-Allow-Origin头为"*",允许任意站点访问文件。只要浏览器检测到响应头带上了CORS,并且允许的源包括了本网站,那么就不会拦截请求响应。浏览器,例如Firefox3.5,Safari4,IE10使用这个头允许跨域HTTP请求。

        只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。但是,后端服务器如果配置Access-Control-Allow-Origin: *,不管withCredentials有没有设置,cookie也带不过去。

跨文档通信

        这种方式允许一个页面的脚本发送文本信息到另一个页面的脚本中,不管脚本是否跨域。在一个window对象上调用postMessage()会异步的触发window上的onmessage事件,然后触发定义好的事件处理方法。一个页面上的脚本仍然不能直接访问另外一个页面上的方法或者变量,但是他们可以安全的通过消息传递技术交流。

JSONP

        JOSNP允许页面接受另一个域的JSON数据,通过在页面增加一个可以从其它域加载带有回调的JSON响应的<script>标签。

        JSONP 的原理就是 利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。JSONP 仅支持 get 方法具有局限性(JSONP是通过动态创建 script 实现的, 动态创建 script 只能发起 get 请求,无法发起post请求)。

WebSocket

        现代浏览器允许脚本直连一个WebSocket地址而不管同源策略。然而,使用WebSocket URI的时候,在请求中插入Origin头就可以标识脚本请求的源。为了确保跨站安全,WebSocket服务器必须根据允许接受请求的白名单中的源列表比较头数据。

Nginx反向代理

        通过nginx配置一个代理服务器(域名与端口号和客户端不同)做跳板机,反向代理访问api.minhung.me接口,并且可以顺便修改cookie中admin.minhung.me信息,方便当前域cookie写入,实现跨域登录。

前端项目(admin.minhung.me:19700)

后端项目(api.minhung.me:19800)

在前端项目nginx配置中添加proxy_pass,将请求的接口代理到 api.minhung.me:19800

 

# 前端nginx配置 
server {
    listen       19700;
    server_name  admin.minhung.me;

    location / {
        proxy_pass   http://api.minhung.me:19800;  #反向代理
        proxy_cookie_domain api.minhung.me:19800 admin.minhung.me:19700; #修改cookie里域名
        index  index.html index.htm;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RexHarrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值