同源策略详解

同源策略详解

💡 原文约2200字/词,阅读约需8分钟。
📝

内容提要

同源策略要求协议、主机、端口相同。它限制跨源读取canvas、iframe内部信息和Ajax响应,但允许脚本、图片等只读加载,目的是防CSRF等攻击。解决方案包括CORS、反向代理、postMessage、WebSocket和JSONP,其中CORS最常用,需处理预检请求和跨域Cookie问题。

🔎

延伸解读

同源策略的“只读”本质

文章指出,同源策略并非完全禁止跨源交互,而是限制跨源“写入”或“修改”操作。例如,通过<script>、<img>等标签可以加载跨源资源,但无法读取其内容或修改其行为;表单提交虽能发送数据,但无法获取响应。这种设计在安全与功能之间取得平衡,读者应理解其核心是保护数据不被恶意读取或篡改。

CORS预检请求的必要性

对于非简单请求,CORS会先发送OPTIONS预检请求,询问服务器是否允许实际请求。文章解释,这是因为浏览器默认会发送实际请求并拦截响应,若请求具有副作用(如POST修改数据),则可能造成危害。预检请求在发送前进行权限验证,避免了危险请求到达服务器,体现了安全前置的思想。

跨域Cookie的配置要点

即使CORS允许跨域读取,Cookie等凭证仍需额外配置。文章强调,fetch需设置credentials: 'include',服务器需返回Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin不能为*。此外,Cookie需设置SameSite=None和Secure,并使用HTTPS。这些细节常导致登录态丢失,开发者需仔细处理。

Canvas污染与CORS修复

跨源图片绘制到Canvas会污染画布,导致无法读取像素数据。文章提到,可通过设置img.crossOrigin = 'anonymous'使图片请求变为CORS模式,从而避免污染。但这也要求服务器返回相应的CORS头,否则图片加载会被阻止。这一机制在图像处理应用中尤为重要,开发者需确保资源服务器支持CORS。

❓

Q&A

同源策略中,什么情况下才算同源?

同源策略要求协议、主机和端口都相同。例如 http://example.com:80 中,协议是 http,主机是 example.com,端口是 80。只有这三者完全一致,才被视为同源。

同源策略会限制哪些操作?

同源策略主要限制三类操作:1. 污染 canvas,无法从跨源 canvas 中提取图像数据;2. 获取 iframe 内部信息,访问跨源 iframe 的大部分信息会被拒绝;3. Ajax 请求失败,跨源 Ajax 请求会被浏览器拦截。

为什么同源策略允许通过 script、img 等标签加载跨源资源?

因为这些标签只能以只读方式获取数据,无法修改或操作跨源资源。例如,通过 script 加载的脚本可以执行,但无法读取其内容;img 可以显示图片,但无法读取像素数据。这种设计在保证安全的同时,允许了必要的资源加载。

CORS 协议是如何工作的?

CORS 是基于 HTTP 的协议,通过请求和响应头来协商跨源访问。对于非简单请求,浏览器会先发送一个 OPTIONS 预检请求,服务器返回允许的配置(如 Access-Control-Allow-Origin),浏览器确认后才发送真实请求。简单请求则直接发送,但响应头仍需包含 CORS 配置。

使用 CORS 时如何处理跨域 Cookie?

需要在 fetch 中设置 credentials: 'include',同时服务器需设置 Access-Control-Allow-Credentials: true,且 Access-Control-Allow-Origin 不能为 *,必须指定具体源。此外,Cookie 需设置 SameSite=None 和 Secure,且必须使用 HTTPS。

除了 CORS,还有哪些解决跨域问题的方法?

常见方法包括:反向代理(如 Nginx 或开发服务器代理)、postMessage(用于窗口间通信)、WebSocket(可绕过同源策略但服务器负担大)、JSONP(利用 script 标签,但已过时)。其中 CORS 是最常用的。

🏷️

标签

➡️

继续阅读