同源策略的例外情况
字数 1994 2025-11-30 03:11:47

同源策略的例外情况

同源策略是浏览器实施的重要安全机制,它阻止一个源的文档或脚本与另一个源的资源进行交互。然而,为了实现特定的功能,存在一些必要的例外情况。

1. 跨域资源写入

  • 描述:同源策略通常允许跨域写入操作。这意味着从一个网页可以自由地向另一个域提交数据(例如,通过HTML表单的<form>提交,或通过JavaScript发起POSTPUTDELETE等请求)。
  • 原理:这类请求默认可以发出,但浏览器通常会限制脚本读取来自不同域的响应。这是一个“单向”的例外,重点在于防止跨域读取敏感数据,而非完全阻止请求的发出。一个典型的应用场景就是用户在一个网站(例如https://social.example)上提交评论表单,数据被发送到另一个域的API(例如https://api.example)。

2. 跨域资源嵌入

  • 描述:同源策略允许通过特定HTML标签将来自不同源的资源嵌入到当前页面中。
  • 原理:浏览器在加载这些嵌入资源时,不会检查其是否同源。然而,嵌入的资源在页面中的访问权限受到严格限制。例如,通过<script>标签引入的跨域JavaScript文件可以执行,但页面的JavaScript不能读取该文件的内容。常见的可嵌入跨域资源标签包括:
    • <script src="...">
    • <link rel="stylesheet" href="...">
    • <img>, <video>, <audio>
    • <iframe>(嵌入的页面受到严格限制,通常无法被父页面的脚本访问)
    • @font-face
    • <object><embed>

3. 跨域资源共享(CORS)

  • 描述:CORS是一种官方的W3C标准,它允许服务器明确地告诉浏览器,哪些外部源有权访问其资源。
  • 原理:这是一个基于HTTP头部的机制。当浏览器需要发起一个跨域HTTP请求时(例如,使用fetchXMLHttpRequest),它会自动在请求头中添加一个Origin字段,表明请求的来源。如果服务器允许该源访问,它将在响应头中包含Access-Control-Allow-Origin,其值可以是具体的源,或通配符*(表示允许任何源)。对于可能产生副作用的非简单请求(如PUT或带有自定义头的POST),浏览器会先发送一个OPTIONS方法的“预检”请求,以确认实际请求是否安全。

4. JSONP(JSON with Padding)

  • 描述:JSONP是一种利用<script>标签嵌入例外来实现跨域数据获取的古老技术,在现代CORS普及前被广泛使用。
  • 原理:它利用了<script>标签可以跨域加载并执行JavaScript代码的特性。客户端预先定义一个回调函数(例如handleData),然后在请求的URL中指定这个回调函数的名称。服务器返回的不是纯JSON,而是一段调用该回调函数的JavaScript代码,并将JSON数据作为参数传入。当脚本加载完成后,浏览器会执行这段代码,从而触发客户端定义的回调函数并处理数据。

5. 文档域降级(document.domain

  • 描述:这是一个历史遗留的例外,主要用于解决具有相同一级域名、不同二级域名的页面间通信问题。
  • 原理:如果两个页面的document.domain都设置为相同的值(例如,blog.example.comapp.example.com都可以设置为example.com),那么浏览器就会将它们视为同源,允许它们相互访问。注意:现代浏览器出于安全考虑,已经对此功能施加了严格限制,通常要求端口也必须相同,并且不允许设置为完全不相关的域或公共后缀(如.com)。

6. 跨文档消息传递(window.postMessage

  • 描述:这是一种安全、可控的跨源通信机制,允许来自不同源的窗口(如<iframe>或新打开的窗口)之间进行数据传递。
  • 原理:发送方窗口调用postMessage方法,指定要发送的数据和目标窗口的 origin(出于安全考虑,应始终指定具体的 origin 而非 *)。接收方窗口通过监听message事件来接收数据。在事件处理程序中,接收方应始终检查事件的origin属性,以验证消息来源的合法性,防止恶意数据注入。

7. WebSocket

  • 描述:WebSocket协议在建立连接时,不受同源策略的限制。
  • 原理:浏览器在发起WebSocket连接握手时,会包含一个Origin头。WebSocket服务器可以根据这个头信息来决定是否接受连接。然而,一旦连接建立,数据就可以在客户端和服务器之间双向自由流动,不受同源策略的干涉。
同源策略的例外情况 同源策略是浏览器实施的重要安全机制,它阻止一个源的文档或脚本与另一个源的资源进行交互。然而,为了实现特定的功能,存在一些必要的例外情况。 1. 跨域资源写入 描述 :同源策略通常允许 跨域写入 操作。这意味着从一个网页可以自由地向另一个域提交数据(例如,通过HTML表单的 <form> 提交,或通过JavaScript发起 POST 、 PUT 、 DELETE 等请求)。 原理 :这类请求默认可以发出,但浏览器通常会限制脚本读取来自不同域的响应。这是一个“单向”的例外,重点在于防止跨域读取敏感数据,而非完全阻止请求的发出。一个典型的应用场景就是用户在一个网站(例如 https://social.example )上提交评论表单,数据被发送到另一个域的API(例如 https://api.example )。 2. 跨域资源嵌入 描述 :同源策略允许通过特定HTML标签将来自不同源的资源 嵌入 到当前页面中。 原理 :浏览器在加载这些嵌入资源时,不会检查其是否同源。然而,嵌入的资源在页面中的访问权限受到严格限制。例如,通过 <script> 标签引入的跨域JavaScript文件可以执行,但页面的JavaScript不能读取该文件的内容。常见的可嵌入跨域资源标签包括: <script src="..."> <link rel="stylesheet" href="..."> <img> , <video> , <audio> <iframe> (嵌入的页面受到严格限制,通常无法被父页面的脚本访问) @font-face <object> 和 <embed> 3. 跨域资源共享(CORS) 描述 :CORS是一种官方的W3C标准,它允许服务器明确地告诉浏览器,哪些外部源有权访问其资源。 原理 :这是一个基于HTTP头部的机制。当浏览器需要发起一个跨域HTTP请求时(例如,使用 fetch 或 XMLHttpRequest ),它会自动在请求头中添加一个 Origin 字段,表明请求的来源。如果服务器允许该源访问,它将在响应头中包含 Access-Control-Allow-Origin ,其值可以是具体的源,或通配符 * (表示允许任何源)。对于可能产生副作用的非简单请求(如 PUT 或带有自定义头的 POST ),浏览器会先发送一个 OPTIONS 方法的“预检”请求,以确认实际请求是否安全。 4. JSONP(JSON with Padding) 描述 :JSONP是一种利用 <script> 标签嵌入例外来实现跨域数据获取的古老技术,在现代CORS普及前被广泛使用。 原理 :它利用了 <script> 标签可以跨域加载并执行JavaScript代码的特性。客户端预先定义一个回调函数(例如 handleData ),然后在请求的URL中指定这个回调函数的名称。服务器返回的不是纯JSON,而是一段调用该回调函数的JavaScript代码,并将JSON数据作为参数传入。当脚本加载完成后,浏览器会执行这段代码,从而触发客户端定义的回调函数并处理数据。 5. 文档域降级( document.domain ) 描述 :这是一个历史遗留的例外,主要用于解决具有相同一级域名、不同二级域名的页面间通信问题。 原理 :如果两个页面的 document.domain 都设置为相同的值(例如, blog.example.com 和 app.example.com 都可以设置为 example.com ),那么浏览器就会将它们视为同源,允许它们相互访问。 注意 :现代浏览器出于安全考虑,已经对此功能施加了严格限制,通常要求端口也必须相同,并且不允许设置为完全不相关的域或公共后缀(如 .com )。 6. 跨文档消息传递( window.postMessage ) 描述 :这是一种安全、可控的跨源通信机制,允许来自不同源的窗口(如 <iframe> 或新打开的窗口)之间进行数据传递。 原理 :发送方窗口调用 postMessage 方法,指定要发送的数据和目标窗口的 origin(出于安全考虑,应始终指定具体的 origin 而非 * )。接收方窗口通过监听 message 事件来接收数据。在事件处理程序中,接收方应始终检查事件的 origin 属性,以验证消息来源的合法性,防止恶意数据注入。 7. WebSocket 描述 :WebSocket协议在建立连接时,不受同源策略的限制。 原理 :浏览器在发起WebSocket连接握手时,会包含一个 Origin 头。WebSocket服务器可以根据这个头信息来决定是否接受连接。然而,一旦连接建立,数据就可以在客户端和服务器之间双向自由流动,不受同源策略的干涉。