什么是跨域?
当前访问的服务器所返回的页面,页面内的JS访问另一个服务器的资源的时候,出现跨域。(本地资源打开的页面去访问服务器,也是跨域)
如何判断跨域?
- 协议是否相同
- 域名是否相同
- 端口号是否相同
举例:http://www.example.com/dir/page.html,
这个url的协议:http
,域名为:example.com
,顶级域名:.com
。主机名:www
(也是三级域名)。端口是80
(默认端口可以省略),它的同源情况如下:
- http://www.example.com/dir2/other.html : 同源
- http://example.com/dir/other.html :不同源
- http://example.com:81/dir/other.html :不同源
⚠️ 注意:域名和域名对应ip算跨域
⚠️ 注意:引入外链资源JS、IMG的时候没有跨域限制,Iframe也可以直接引入跨域页面,但无权限访问iframe
同源策略
- 来源:
1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。
浏览器的同源策略限制了来自不同源的“document”或脚本,对当前“document”读取或设置某些属性。注意: 对于当前页面来说,页面内存放JavaScript文件的域并不重要,重要的是加载JavaScript页面所在的域是什么。
比如:a.com通过加载一下代码:
1
2 > <script src=http://b.com/b.js ></script>
>
加载b.com上的b.js是运行在a.com页面上的,因此对于当前打开的页面(a.com页面)来说,b.js的Origin就应该是a.com而非b.com。
在浏览器中,
<script>
、<img>
、<iframe>
、<link>
等标签都可以跨域加载资源,而不受同源策略的限制。这些带“src”属性的标签每次加载时,实际上是由浏览器发起了一次GET请求。不同于XMLHttpRequest的是,通过src属性加载的资源,浏览器限制了JavaScript的权限,使其不能读、写返回的内容。
在HTML5中,有些元素提供了支持CORS(Cross-Origin Resource Sharing)(跨域资源共享)的属性,这些元素包括<img>
,<video>
,<script>
等,而提供的属性名就是crossOrigin属性。
- 目的
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?
很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
- 限制行为
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
实现跨域的几种方法
iframe
如果两个网页不同源,就无法拿到对方的DOM,也无法进行通信。典型的例子是iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信。
解决方法:
- document.domain(如果两个窗口一级域名相同,只是二级域名不同)
- 片段识别符(fragment identifier)
1 | //父窗口可以把信息,写入子窗口的片段标识符 |
-
window.name
无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。window.name容量很大,可以放置非常长的字符串.(ps:个人感觉也是一个小tip) -
window.postMessage (MessageChannel)
1 | var popup = window.open('http://bbb.com', 'title'); |
1 | //父窗口和子窗口都可以通过message事件,监听对方的消息。 |
AJAX
1. JSONP
- 特点:利用script标签实现跨域,兼容性好。
- 示例:
1 | // jsonp |
url返回的即是将数据传入jsonpCallback
并调用执行的脚本。而script
标签会让它自动执行。
2. WebSocket
- WebSocket 教程—阮一峰 (websocket没有同源限制,客户端可以与任意服务器通信,顺便说一下它最大的特点,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。)
3. CORS
CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。
注意:普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置
1 | // 前端设置是否带cookie |
nginx代理跨域,node开启服务作为代理跨域
跨域原理: 同源策略只是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。