请解释同源策略 (Same-Origin Policy)。什么是跨域 (Cross-Origin)?

推荐答案

同源策略 (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): 指的是 httphttps 等。
  • 域名 (host): 指的是 www.example.comapi.example.com 等。
  • 端口号 (port): 指的是 URL 中指定的端口号,例如 804438080 等。如果 URL 中没有明确指定端口号,则会使用默认端口,http 默认端口是 80https 默认端口是 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 元素,窃取用户信息。

同源策略通过限制不同源之间的交互来降低这些风险。

跨域的具体表现

跨域通常表现为以下几种情况:

  1. XMLHttpRequest/Fetch 请求跨域: 当 JavaScript 代码使用 XMLHttpRequest 或 Fetch API 发起请求时,如果请求的目标资源与当前页面的源不同,浏览器会阻止该请求的执行或限制其访问响应内容。
  2. DOM 操作限制: 如果页面试图访问不同源的 iframe 或者 window 对象中的 DOM 元素,浏览器也会阻止此类操作。
  3. Cookie 限制: 只有同源的页面才能访问彼此的 Cookie。

如何解决跨域问题

由于同源策略的存在,开发中经常会遇到跨域问题。解决跨域问题的方法有很多,常见的包括:

  • JSONP: 通过 <script> 标签的 src 属性来加载数据,只能用于 GET 请求,并且服务器需要进行特殊处理返回特定格式的数据。
  • CORS (Cross-Origin Resource Sharing): 一种 W3C 标准,允许服务器声明允许哪些源访问它的资源,目前是主流的跨域解决方案。
  • 代理服务器: 通过同源的服务器转发请求,绕过浏览器的同源策略限制。
  • WebSocket: 一种全双工通信协议,不受同源策略限制。
  • document.domain: 允许同域名下子域之间进行跨域访问,前提是两个页面的 document.domain 设置成一样。

理解同源策略是前端开发的基础,掌握如何处理跨域问题也是前端工程师的必备技能。

纠错
反馈