前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CS 可视化: CORS

CS 可视化: CORS

作者头像
小弟调调
发布2024-01-17 14:21:16
920
发布2024-01-17 14:21:16
举报
文章被收录于专栏:埋名埋名

原文: https://dev.to/lydiahallie/cs-visualized-cors-5b8h 作者: Lydia Hallie 翻译: ChatGTP

偶尔,每个开发者都会在控制台中看到那个讨厌的大红色 Access to fetched has been blocked by CORS policy 错误!😬 尽管有一些快速消除此错误的方法,但今天我们不要掉以轻心!相反,让我们看看 CORS 到底在做什么,以及为什么它实际上是我们的朋友 👏🏼

❗️ 在本博文中,我不会解释 HTTP 基础知识。如果您想了解有关 HTTP 请求和响应的更多信息,我之前写过一篇小博文,尽管我在示例中使用的是 HTTP/1.1 而不是 HTTP/2,但这不会影响 CORS。

在前端,我们经常希望显示位于其他地方的数据!在我们可以显示这些数据之前,浏览器首先必须向服务器发出请求以获取数据!客户端发送带有服务器需要的所有信息的 HTTP 请求,以便将数据发送回客户端 🙂

假设我们正在尝试从位于 api.website.com 的服务器上获取一些用户信息,以在我们的 www.mywebsite.com 网站上显示!

太好了!😃 我们刚刚向服务器发送了一个 HTTP 请求,然后它以我们请求的 JSON 数据进行了响应。

让我们尝试相同的请求,但来自另一个域。我们不再从 www.mywebsite.com 发出请求,而是从位于 www.anotherdomain.com 的网站发出请求。

等等,什么?我们发送了完全相同的请求,但这次浏览器显示了一个奇怪的错误?

我们刚刚看到了 CORS 的作用!💪🏼 让我们看看为什么会发生这个错误,以及它到底意味着什么。

✋🏼 同源策略

网络实施了一种称为同源策略的机制。默认情况下,我们只能访问与我们请求的起源相同的资源!💪🏼 例如,加载位于 https://mywebsite.com/image1.png 的图像是完全可以的。

当资源位于不同的(子)域、协议或端口时,资源就是跨源的!

好了,但是为什么同源策略要存在呢?

假设同源策略不存在,你不小心点击了你阿姨在Facebook上发给你的许多病毒链接之一。该链接将您重定向到一个带有嵌套的 iframe 的“邪恶网站”,该 iframe 加载了您银行的网站,并通过一些已设置的 cookie 成功登录了您!😬

这个“邪恶网站”的开发者使得网站能够访问此 iframe 并与您银行网站的 DOM 内容交互,以便代表您向他们的帐户发送资金!

是的... 这是一个巨大的安全风险!我们不希望任何人都能够随意访问一切 😧

幸运的是,同源策略在这里帮了我们!该策略确保我们只能访问相同源的资源。

在这种情况下,源 www.evilwebsite.com 尝试访问 www.bank.com 的跨源资源!同源策略阻止了这种情况发生,并确保邪恶网站的开发人员不能随意访问我们的银行数据 🥳

好的,那么... 这与 CORS 有什么关系呢?

🔥 客户端 CORS

尽管同源策略实际上仅适用于脚本,但浏览器为 JavaScript 请求“扩展”了此策略:默认情况下,我们只能访问相同源的获取的资源!

嗯,但是... 我们经常需要访问跨源资源 🤔 也许我们的前端需要与后端 API 交互以加载数据?为了安全地允许跨源请求,浏览器使用一种称为CORS的机制!🥳

CORS 代表跨源资源共享。尽管浏览器禁止我们访问未位于相同源的资源,但我们可以使用 CORS 稍微修改这些安全限制,同时确保我们安全地访问这些资源 🎉

用户代理(例如浏览器)可以使用 CORS 机制,以根据 HTTP 响应中特定 CORS 头的值允许跨源请求,否则这些请求将被阻止!✅

当发出跨源请求时,客户端会自动向我们的 HTTP 请求添加额外的头部:OriginOrigin 头的值是请求的起源!

为了让浏览器允许访问跨源资源,它期望从服务器响应中获得某些头部,这些头部指定此服务器是否允许跨源请求!

💻 服务器端 CORS

作为服务器开发者,我们可以通过向 HTTP 响应添加额外的头部来确保允许跨源请求,所有这些头部都以 Access-Control-* 开头 🔥 根据这些 CORS 响应头的值,浏览器现在可以允许某些本来会被同源策略阻止的跨源响应!

尽管我们可以使用多个 CORS 头部,但有一个头部是浏览器需要以允许访问跨源资源的:Access-Control-Allow-Origin!🙂 该头部的值指定允许访问资源的起源

如果我们正在开发一个应该允许 https://mywebsite.com 访问的服务器,我们可以将该域的值添加到Access-Control-Allow-Origin头部!

🎉 太棒了!这个头部现在已经添加到服务器发送回客户端的响应中。通过添加这个头部,同源策略将不再限制我们接收位于 https://api.mywebsite.com 起源的资源,如果我们是从 https://mywebsite.com 发送请求的话!

浏览器中的 CORS 机制会检查 Access-Control-Allow-Origin 头部的值是否等于请求发送的 Origin 的值 🤚🏼

在这种情况下,我们请求的起源是 https://www.mywebsite.com,它在 Access-Control-Allow-Origin 响应头部中有记录!

太好了!🎉 我们成功地接收了跨源资源!那么当我们尝试从未在 Access-Control-Allow-Origin 头部中列出的起源访问这些资源时会发生什么呢?🤔

啊,是的,CORS 抛出了有时候令人沮丧的臭名昭著的错误!但现在我们实际上看到它是完全有道理的

代码语言:javascript
复制
'Access-Control-Allow-Origin' 头部的值  'https://www.mywebsite.com' 不等于  提供的起源。 

在这种情况下,提供的起源是 https://www.anotherwebsite.com。然而,服务器在 Access-Control-Allow-Origin 头部的允许起源列表中没有这个提供的起源!CORS 成功阻止了请求,我们无法在代码中访问获取的数据 😃

CORS 还允许我们将通配符 * 添加为允许起源的值。这意味着所有起源的请求都可以访问所请求的资源,因此请小心!

Access-Control-Allow-Origin 是我们可以提供的许多 CORS 头部之一。服务器开发者可以通过扩展服务器的 CORS 策略来允许或拒绝某些请求!💪🏼

另一个常见的头部是 Access-Control-Allow-Methods 头部!只有在列出的方法中发送的跨源请求才会被 CORS 允许。

在这种情况下,只有使用 GETPOSTPUT 方法的请求将被允许!其他方法如 PATCHDELETE 将被阻止 ❌

如果你对其他可能的 CORS 头部是什么以及它们的用途感兴趣,请查看这个列表。

说到 PUTPATCHDELETE 请求,CORS 实际上以不同的方式处理这些请求!🙃 这些“非简单”请求启动了一种称为预检请求的东西!

🚀 预检请求

CORS 有两种类型的请求:简单请求预检 请求。请求是简单还是预检取决于请求中的一些值(别担心,你不必记住这些 lol)。

当请求是 GETPOST 方法且没有自定义头部时,请求是简单的!任何其他请求,例如带有 PUTPATCHDELETE 方法的请求,将进行预检。

如果你只是想知道请求必须满足哪些条件才能成为简单请求,MDN 有 一个有用的列表!

好了,但是“预检请求”到底是什么意思,为什么会发生这种情况呢?

在实际请求发送之前,客户端会生成一个预检请求!预检请求包含关于我们即将进行的实际请求的信息,在其 Access-Control-Request-* 头部中 🔥

这使得服务器了解浏览器正试图发起的实际请求的信息:请求的方法是什么,有附加头部等等。

服务器收到这个预检请求,并以服务器的 CORS 头部为空的 HTTP 响应进行响应!浏览器接收到预检响应,其中除了 CORS 头部之外不包含任何数据,并检查是否应该允许 HTTP 请求!✅

如果是这样,浏览器将实际请求发送到服务器,然后服务器以我们请求的数据进行响应!

然而,如果不是这样,CORS 将阻止预检请求,实际请求将不会发送 ✋🏼 预检请求是防止我们访问或修改没有启用任何 CORS 策略的服务器上的资源的好方法(尚未启用)!服务器现在受到了潜在的不受欢迎的跨源请求的保护 😃

💡 为了减少与服务器的往返次数,我们可以通过向我们的 CORS 请求添加一个 Access-Control-Max-Age 头部来缓存预检响应!通过这种方式,我们可以缓存预检响应,浏览器可以在不发送新的预检请求的情况下使用它!

🍪 凭据

默认情况下,Cookie、授权头和 TLS 证书仅在同源请求上设置!然而,我们可能希望在跨源请求中使用这些凭据。也许我们想在请求中包含服务器可以用来识别用户的 Cookie!

尽管 CORS 默认不包括凭据,但我们可以通过添加 Access-Control-Allow-Credentials CORS 头部来更改这一点!🎉

如果我们想要在跨源请求中包含 Cookie 和其他授权头,我们需要在请求上将 withCredentials 字段设置为 true,并在响应中添加 Access-Control-Allow-Credentials 头部。

搞定了!我们现在可以在跨源请求中包含凭据了 🥳

虽然我认为我们都可以一致同意,CORS 错误有时可能让人沮丧,但它确实使我们能够在浏览器中安全地进行跨源请求(它应该得到更多的关注 lol) ✨

显然,同源策略和 CORS 还有很多内容,我在这篇博文中无法涵盖所有!幸运的是,有许多出色的资源,比如这个,或者 W3 规范,如果你想要更多阅读 💪🏼

而且,如常,随时与我联系!😊

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JSdig 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ✋🏼 同源策略
  • 🔥 客户端 CORS
  • 💻 服务器端 CORS
  • 🚀 预检请求
  • 🍪 凭据
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档