03.05 什么是跨域,跨域的实现方式有哪些?

用户65981909


查了一些资料,再结合我之前的了解,给大家介绍一下,如果有说的不对的地方,请大家留言指正。


什么是跨域

浏览器有一个毛病(策略):请求url的协议、域名、端口必须相同,才允许访问(通信),否则就不允许访问,是跨域。

https(协议)://www.wukong.com(域名和端口)/index.html


比如:

https://www.wukong.com/index.html

http://www.wukong.com/index.html

这样就不允许通信,因为协议不同。


完整的举个例子:

你有服务器A和服务器B,服务器A上存着CSS和JS脚本,服务器B上存着HTML,HTML页面上的CSS和JS都是链接的服务器A上面的。

然后用浏览器打开服务器B上面的xxx.html,页面打开后可以正常渲染出样式,可以运行JS脚本,这样就是跨域名,跨端口,跨协议

如何解决跨域

  • JSONP:利用了script标签不受同源策略的限制,通过script加载服务器A的资源。

  • Proxy代理:使用服务器接口做代理,因为同源策略之针对浏览器。

  • CORS:跨域资源共享,这个就是浏览器后悔了,出了一个跨域访问机制(XMLHttpRequest),低版本IE不支持。

  • Postmessage:HTML5新增的跨域机制。

  • Nginx反向代理:相当于Proxy代理。


希望我的回答可以帮助到你!


会点代码的大叔


在介绍跨域之前,我们需要先了解一下同源策略。那么什么是浏览器的同源策略呢?

同源

同源是指协议,域名,端口完全相同。

比如

  • http://www.example.com/index.do

  • http://www.example.com/login.do

而下面的任意一种都是不同源的。

协议不同

  • http://www.example.com/index.do

  • https://www.example.com/login.do

域名不同

  • https://www.example.com/index.do

  • https://subdomain.example.com/login.do

  • https://www.test.com/login.do

端口不同

  • http://www.example.com:80/index.do

  • http://www.example.com:8080/login.do

同源策略

同源策略(SOP,Same origin policy)是指作为浏览器最基本安全功能的一种约定,它对以下请求进行限制来降低受到XSS、CSFR等攻击的风险。

  1. 浏览器的存储

  2. 浏览器DOM对象和脚本

  3. AJAX请求


那么现在可以来认识一下什么是跨域了。

跨域

广义上的跨域是指一个域下的资源去请求另一个非同源域的资源,而狭义上的跨域是指同源策略限制的这一类请求。

解决跨域问题的常用手段:

  • 跨域资源共享(CORS)

服务器端指定请求头中的Access-Control-Allow-Origin字段即可。

'Access-Control-Allow-Origin': '*' // *代表所有,在实际开发中,应当遵循最小授权的原则来指定域名

  • 代理服务器

同源策略是针对浏览器的,对于服务器是没有限制的,所以只需要制作一个代理服务器,然后将原来的请求转发到目标服务器即可。

  • nginx反向代理

静态代理

在静态代理服务器中加入请求头信息,和第一种相似

location / {
add_header Access-Control-Allow-Origin *;
}

代理服务器作为中间跳板

和第二种相似

  • jsonp方式

js,html,css对应的标签是允许跨域加载静态资源的,但是jsonp只支持get方式。


还有很多方式可以解决跨域问题,你还有哪些葵花宝典,发来欣赏一下可好?


飞升的码农


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应用开发的授权类似。不过在安全性和便利性之间的取舍不是那么容易的。


个人手敲,欢迎批评指正。


迁徙de麻雀


关于,跨域问题,我刚写了一篇文章,现在就贴过来供给参考

大家有时经常问什么是跨域问题,这个问题并不是一句话能回答的,因为我也不知道你说的是哪一种性质的跨域,比如说,你说的是不同域名的session共享呢?还是说ajax跨域问题呢。不管是哪种的跨域,我今天的文章中都给它列出来,并附上具体的操作方法,供大家借鉴,一起学习交流。

先说session共享的跨域问题,一个域名下都会保持一份会话,跨域就是说从一个域名到另一个域名这个会话还能继续保持,很常见的就是在一个网站跳到另一个网站还是继续保持登录状态,一般情况下从一个域名下跳到另一个域名下,登录状态是会丢失的,如果说没有丢失,那么就是进行了跨域处理。

图片来之互联网

关于跨域处理有两个级别的处理:

1.两个不同的二级域名session共享

这种级别的处理做个简单的设置就可以了,一句代码就可以做到会话保持,我以php为例,假如说你是是个电商网站,一个是母婴频道,一个是数码频道,他们是两个不同的二级域名,比如一个是muying.yourdomain.com,一个是dianzi.yourdomain.com,如果不做任何处理的话,从muying.yourdomain.com跳转到dianzi.yourdomain.com登录状态是没法保持的,要想做到两个二级域名的跨域就可以去修改php.ini的配置,修改改配置项session.cookie_domain,如果觉得修改配置项嫌麻烦的话,也可以修改php代码,在自己的php框架里处理session的地方加上这么一句就可以了

ini_set("session.cookie_domain\


分享到:


相關文章: