同源策略的例外情况
字数 1994 2025-11-30 03:11:47
同源策略的例外情况
同源策略是浏览器实施的重要安全机制,它阻止一个源的文档或脚本与另一个源的资源进行交互。然而,为了实现特定的功能,存在一些必要的例外情况。
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服务器可以根据这个头信息来决定是否接受连接。然而,一旦连接建立,数据就可以在客户端和服务器之间双向自由流动,不受同源策略的干涉。