Web场景中包含了脚本执行功能的用户代理(典型的是浏览器),对跨域访问实施了安全限制(遵循同源策略),导致大家在开发中碰到跨域访问时需要使用特定机制来实现。
跨域的域这里的域,不是单纯的域名。IETF的RFC6454标准(2011年12月正式发布)说明了源(Origin)的概念。源是一组URI的集合,而这一组URI的特征是完全符合一个三元组(uri-scheme,uri-host,uri-port)。大家所说的跨域访问,实际上是跨源访问。后续回答中的描述中域和源可能混用。
依据三元组很容易划分哪些URI同源,哪些不同源。下面两张出自RFC6454的示例列表(第一张3个同源,第二张都不同源):
协议标准将scheme、host、port都作为源的分组条件,是基于以下考虑的:
1、不同的协议一般会实施不同的安全策略,比如https通过TSL加密传输数据提高安全性。
2、父子域名配合端口,在稍大的平台中其实都是分开部署(这里自然还含架构设计等),且有不同安全级别的要求。比如京东登录使用的是passport.jd.com子域名,很多子系统的登录入口都在这里。
IE比较调皮,未将端口加入分组要素,也就是不同端口并不跨源(第二张图片前两个URI在IE在就是同源),同时对于域也有自己安全区域的一套机制。
跨域的安全问题Web领域的用户代理,实际包括浏览器、仅实现HTTP功能的编程组件,爬虫工具等。浏览器需要渲染界面(html、css)、执行脚本(js),同时浏览器是一个公共环境,大家可以用它浏览来自全世界Web服务器提供的资源信息。因为有了脚本执行能力(包括js以及各种插件扩展),如果不加限制自然会引发了诸多的安全问题。跨域方面的安全问题主要包括跨站脚本(XXS)、跨站点请求伪造(CSRF)等。下图示owasp发布的2017年10大威胁,详细信息可以上owasp官网查看。
跨域的安全问题主要是基于同源策略(Same-origin policy)来限制。
简单来说同源策略主要保护是某一个源相关的js对象以及其它可访问资源(比如cookie、本地存储等)。比如:很多服务器基于 cookie信息来发布敏感信息或采取状态改变操作。必须在客户端维护由不相关站点提供的内容之间的严格分离,以防止数据机密性或完整性的丢失。
跨域访问策略用户代理对跨源访问会做诸多限制,但同时也会提供跨源访问的机制。服务端也会有限制客户端跨域访问的需求,典型比如的盗链问题。所以跨域访问需要清楚服务端和客户端各自的限制和需求。偶主要分下面两个场景来描述可用策略。
跨源本地访问
因为frame的存在,大家可以在同一页面包含不同源的资源;大家也可以在新窗口中打开不同源的页面。
大家可以通过跨文档消息来实现交互:通过window对象异步调用postMessage方法,在另一个窗口触发onmessage事件。window对象可以通过多种方式获取到引用,比如iframe的contentWindow、window.open返回的window对象、或者在window.frames中查找。
跨源访问不同服务器资源
可用策略多种多样,偶把他们归为以下几类:
利用漏洞:如Jsonp,这个和XXS有异曲同工之妙。浏览器下载并执行非同源js是必要的,但是存在安全隐患,所以不要乱引用三方脚本。
插件扩展:通过flash,silverlight等插件扩展避过浏览器的直接限制,充当客户端代理层。补充协议:跨域资源共享(CORS)目前由WHATWG维护。本质上是客户端和服务端协商机制。详情可参考fetch文档或者MDN文档说明。换协议:Websocket不使用同源策略,但浏览器提供Origin头,服务端可以维护白名单来进行跨域限制。服务端代理:通过nginx之类的代理服务器将不同源的信息转化为同源信息,客户端就不存在跨域问题了。也可以自己实现一个代理组件,这里依赖的就是HTTP组件并未提供严苛的同源策略实现,你甚至可以根据需要修改Origin头来欺骗对方服务器。父子域名:可通过更改document.domain来临时放宽同源限制。如果你思维够抽象,你会发现跨域访问和IPC机制很相似,只要你想得透彻,方式方法很多。
Tips:MDN是个不错的Web开发参考网站,由mozilla维护,可用来做知识点补充(深度不太够,但是包含范围很广)和API参考。IE的官方文档关于API的参考也是重定向到这里,其实想想也挺搞笑的,实现走非主流路线,文档倒是走到一起了。
总结跨域背后是安全性问题,包含有还有非常多的规范和实现细节,比如安全上下文、源的继承等等。与跨域访问需求相对的,大家有时还需要非常严格的跨域访问限制,防止各种安全问题出现。
跨域访问需求很广泛,以后可能还会出更多的规范放宽同源限制,原则应该都是需要客户端和服务端预先了解到风险并确认风险,跟APP应用开发的授权类似。不过在安全性和便利性之间的取舍不是那么容易的。
个人手敲,欢迎批评指正。
css的扩写,css样式重复,dw导航菜单css,css 点击可展开折叠,css中红色的rgb,html css3微盘,js操作css伪类