推荐答案
同源策略 (Same-Origin Policy) 是一种重要的浏览器安全机制,它限制了来自不同源的文档或脚本如何与另一个源的资源进行交互。所谓“同源”指的是协议 (protocol)、域名 (host) 和端口号 (port) 都完全相同。只有这三者完全一致,才能被认为是同源。
跨域 (Cross-Origin) 则发生在当一个请求的目标资源的源与发起请求的页面的源不同时。此时,浏览器会根据同源策略阻止该请求的执行,或者限制其访问响应内容。例如,一个页面从 http://www.example.com
发起请求到 https://api.example.com
就属于跨域,因为协议不同;从 http://www.example.com
发起请求到 http://www.test.com
也属于跨域,因为域名不同。
本题详细解读
什么是同源
同源策略的核心在于“同源”,它定义了浏览器在安全方面应该遵循的规则。理解“同源”是理解同源策略的关键。当两个 URL 的协议 (protocol)、域名 (host) 和端口号 (port) 都一致时,我们称这两个 URL 为同源。
- 协议 (protocol): 指的是
http
、https
等。 - 域名 (host): 指的是
www.example.com
、api.example.com
等。 - 端口号 (port): 指的是 URL 中指定的端口号,例如
80
、443
、8080
等。如果 URL 中没有明确指定端口号,则会使用默认端口,http
默认端口是80
,https
默认端口是443
。
只有当这三个部分都完全一致时,才认为两个 URL 同源。
举例说明:
URL 1 | URL 2 | 是否同源 | 原因 |
---|---|---|---|
http://www.example.com |
http://www.example.com |
是 | 协议、域名和端口号都相同 |
http://www.example.com |
https://www.example.com |
否 | 协议不同 |
http://www.example.com |
http://api.example.com |
否 | 域名不同 |
http://www.example.com:8080 |
http://www.example.com |
否 | 端口号不同,url2隐式默认80端口 |
http://www.example.com |
http://www.example.com/path |
是 | 虽然有路径,但是协议、域名和端口号都相同,仍然是同源 |
http://www.example.com |
http://www.example.com:80 |
是 | 端口号虽然显式写出,但都是默认80端口 |
同源策略的作用
同源策略的主要作用是保护用户的信息安全。如果没有同源策略,恶意网站就可以轻易地访问其他网站的用户数据,例如用户的 Cookie、LocalStorage、IndexDB 等,这会导致严重的安全问题,包括但不限于:
- CSRF (Cross-Site Request Forgery) 攻击: 恶意网站可以冒充用户向其他网站发送请求。
- XSS (Cross-Site Scripting) 攻击: 恶意脚本可以访问其他网站的 DOM 元素,窃取用户信息。
同源策略通过限制不同源之间的交互来降低这些风险。
跨域的具体表现
跨域通常表现为以下几种情况:
- XMLHttpRequest/Fetch 请求跨域: 当 JavaScript 代码使用 XMLHttpRequest 或 Fetch API 发起请求时,如果请求的目标资源与当前页面的源不同,浏览器会阻止该请求的执行或限制其访问响应内容。
- DOM 操作限制: 如果页面试图访问不同源的 iframe 或者 window 对象中的 DOM 元素,浏览器也会阻止此类操作。
- Cookie 限制: 只有同源的页面才能访问彼此的 Cookie。
如何解决跨域问题
由于同源策略的存在,开发中经常会遇到跨域问题。解决跨域问题的方法有很多,常见的包括:
- JSONP: 通过
<script>
标签的src
属性来加载数据,只能用于 GET 请求,并且服务器需要进行特殊处理返回特定格式的数据。 - CORS (Cross-Origin Resource Sharing): 一种 W3C 标准,允许服务器声明允许哪些源访问它的资源,目前是主流的跨域解决方案。
- 代理服务器: 通过同源的服务器转发请求,绕过浏览器的同源策略限制。
- WebSocket: 一种全双工通信协议,不受同源策略限制。
- document.domain: 允许同域名下子域之间进行跨域访问,前提是两个页面的
document.domain
设置成一样。
理解同源策略是前端开发的基础,掌握如何处理跨域问题也是前端工程师的必备技能。