内容提要
同源策略要求协议、主机、端口一致,本质是限制跨源读取,防止CSRF等攻击。跨源可加载脚本、图片等资源,但无法读取或修改内容。应对方式包括CORS、反向代理、postMessage、WebSocket和JSONP。CORS需处理预检请求及跨源Cookie问题,要求SameSite=None、Secure和HTTPS。
延伸解读
同源策略的本质:只读不写
文章指出,同源策略限制的是跨源读取,而非跨源写入。跨源可以加载脚本、图片、样式等资源,但无法读取或修改其内容。例如,iframe 可以显示页面,但不能操作其 DOM;表单可以提交数据,但无法读取响应。这种设计在安全性和可用性之间取得平衡,允许资源嵌入,同时防止数据泄露。
CORS 预检请求的作用与必要性
对于非简单跨源请求,浏览器会先发送 OPTIONS 预检请求,询问服务器是否允许实际请求。预检请求包含 Access-Control-Request-Method 和 Access-Control-Request-Headers 头,服务器通过响应头如 Access-Control-Allow-Methods 等告知允许的条件。预检机制可以防止实际请求直接到达服务器并执行危险操作,因为浏览器默认会拦截响应,但请求本身可能已产生副作用。
跨源 Cookie 的额外要求
即使 CORS 配置正确,跨源携带 Cookie 仍需满足多个条件:fetch 需设置 credentials: 'include';服务器需返回 Access-Control-Allow-Credentials: true,且 Access-Control-Allow-Origin 不能为 *,必须指定具体源;Cookie 需设置 SameSite=None 和 Secure,并且页面必须使用 HTTPS。Chrome 80 后 SameSite 默认为 Lax,导致跨源 Cookie 默认不发送,可能影响登录状
其他跨源通信方案与注意事项
除 CORS 外,文章提到反向代理、postMessage、WebSocket 和 JSONP。反向代理通过同源转发避免跨源问题;postMessage 用于窗口间通信,需验证 event.origin 以确保安全;WebSocket 不受同源策略限制,但服务器负载较高;JSONP 是历史方案,现已少用。此外,CORP 响应头可限制资源被跨源引用,默认行为类似 cross-origin。
Q&A
同源策略中,什么情况下两个URL被认为是同源的?
当两个URL的协议、主机和端口都完全一致时,它们就是同源的。例如,http://example.com:80 的协议是http,主机是example.com,端口是80。
同源策略的本质是什么?它主要限制什么?
同源策略的本质是限制跨源读取,即允许跨源加载资源(如脚本、图片),但禁止读取或修改这些资源的内容。它主要防止CSRF攻击和恶意操作iframe。
为什么跨源请求可以发送成功,但JavaScript却无法读取响应?
因为同源策略限制的是读取操作,而不是发送请求。跨源请求会正常到达服务器并执行,但浏览器会拦截响应,阻止JavaScript访问返回的数据,除非服务器通过CORS明确允许。
CORS预检请求是什么?它有什么作用?
预检请求是一个OPTIONS请求,用于在发送实际跨源请求前,先询问服务器是否允许该请求。它包含Access-Control-Request-Method和Access-Control-Request-Headers头,可以避免实际请求直接执行可能带来的风险。
使用CORS进行跨源请求时,如何处理Cookie等认证信息?
需要设置credentials: 'include',同时服务器必须返回Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin不能为*,必须指定具体源。此外,Cookie需设置SameSite=None和Secure,并且必须使用HTTPS。
除了CORS,还有哪些方法可以解决跨源通信问题?
可以使用反向代理(如nginx或开发服务器代理)、postMessage(用于窗口间通信)、WebSocket(绕过同源策略但服务器负载高)以及JSONP(老旧技术,现已少用)。