返回

CORs 战 SameSite 的故事

前端

CORS 和 SameSite 是两个密切相关的 Web 安全概念。CORS(跨域资源共享)允许浏览器向跨域服务器发送请求,而 SameSite 则是一种 HTTP 头,用于指定 Cookie 是否可以跨域发送。

最近,我遇到一个项目,需要在开发环境、测试环境和线上环境中进行跨域请求。一开始,我使用传统的 CORS 解决方法,即在服务端设置 CORS 白名单,并在前端代码中设置 withCredentials。这种方法在开发环境和测试环境中运行良好,但在线上环境中却遇到了问题。

在线上环境中,当我尝试向跨域服务器发送请求时,浏览器会疯狂刷新。我花了很长时间才定位到问题所在:SameSite 属性。

SameSite 属性是一个 HTTP 头,用于指定 Cookie 是否可以跨域发送。SameSite 属性有三个可能的值:

  • Lax:Cookie 可以随同跨域请求发送,但只能在GET、HEAD 和 POST请求中发送。
  • Strict:Cookie 只能随同同源请求发送。
  • None:Cookie 可以随同任何类型的请求发送。

在默认情况下,SameSite 属性的值为 Lax。这意味着,如果我在前端代码中设置 withCredentials,浏览器会自动在跨域请求中发送 Cookie。但是,在某些情况下,浏览器可能会阻止发送 Cookie。例如,如果请求的 URL 包含敏感信息,或者如果请求是通过一个不安全的协议(如 HTTP)发起的。

在我的项目中,SameSite 属性的值被设置为 Strict。这意味着,浏览器不会在跨域请求中发送 Cookie。因此,当我尝试向跨域服务器发送请求时,浏览器会疯狂刷新。

为了解决这个问题,我尝试了两种方法:

  • SSR(服务端渲染) :SSR 是一种渲染技术,它允许在服务端渲染 HTML。这意味着,当浏览器请求一个页面时,服务端会先将该页面渲染成 HTML,然后将 HTML 发送给浏览器。这样,浏览器就不需要再向跨域服务器发送请求,从而避免了 SameSite 问题。
  • 预渲染 :预渲染是一种渲染技术,它允许在构建时将 HTML 渲染成静态文件。这意味着,当浏览器请求一个页面时,浏览器可以直接从静态文件中获取 HTML,而不必向服务器发送请求。这样,浏览器就不需要再向跨域服务器发送请求,从而避免了 SameSite 问题。

最终,我使用 SSR 技术解决了这个问题。我将项目中的所有页面都渲染成了 HTML,然后将 HTML 文件部署到 CDN 上。这样,当浏览器请求一个页面时,浏览器可以直接从 CDN 上获取 HTML,而不必向跨域服务器发送请求。

通过使用 SSR 技术,我成功地解决了 CORS 与 SameSite 的问题。我希望我的经历能够帮助到其他遇到同样问题的人。