获取API;如果响应是不透明的,为什么要使用“no-cors”模式?

The*_*Pea 7 fetch cors fetch-api

我读了这个问题这个问题。前者只解释了“no-cors”与“same-origin”;后者建议 'no-cors' 没有用,因为不透明响应(Javascript 无法读取/执行任何有用的操作):

你基本上从不想在实践中使用 mode: 'no-cors'——除非在一些非常有限的情况下。那是因为设置模式:'no-cors' 实际上对浏览器说的是,“在任何情况下都阻止我的前端 JavaScript 代码查看响应正文和标题的内容。” 在大多数情况下,这显然不是您想要的。

有人可以告诉我们这些“有限情况”的例子是什么,我们希望使用“无cors”(即使响应是不透明的?)

我能想到的唯一情况是一种单向通信;如果客户端向服务器发送 GET 或 POST 就足够了,那么服务器就可以跟踪请求的发生;(例如,增加请求计数器);...

...那么响应是一个 OpaqueResponse 就足够了;即客户端只需要知道请求是否成功(状态 200),不需要任何负载响应。

我的想法是一个有效的例子吗?有人可以推荐其他可能性/用例/'no-cors'用法的例子吗?

eed*_*rah 10

请记住,CORS 设置不会阻止请求到达服务器 - 这就是身份验证和 CSRF 的用途。相反,它会阻止页面读取响应。请求依然是:

  1. 从页面发送,
  2. 浏览器添加Origin标题,
  3. 它仍然由服务器处理(通常 - CORS 与此无关,尽管可能有其他安全措施),
  4. 返回时,浏览器检查响应标头中的Access-Control-Allow-Origin. 如果它与浏览器认为的相符,Origin则浏览器会让页面看到请求的结果。

这就是关键 -同源策略和 CORS 设置不允许协作浏览器中的页面查看响应

另请注意,上面有一个步骤 0.,这是发送一个 OPTIONS“飞行前检查”,以检查如果请求通过,是否允许页面查看结果?如果没有,那么他们认为发送请求没有什么意义——但这只是一个假设。

现在来解答这个问题

mode: no-cors做了两件事:

  1. 它说我不需要看到结果
  2. 所以它不会发送飞行前检查

在我的脑海中,这就是我认为我可以用它来做的事情(其中一些是邪恶的)

  • 任何时候我不需要查看响应,例如日志记录、跟踪或黑客攻击;当前端代码本质上是try { const notNeeded = fetch(...) } catch { console.log('Tough luck, do nothing') }
  • 任何时候我想通过不发送预检检查来尽快将数据发送到服务器。当我真正需要时,我总是可以发送带有 CORS 的 GET 来读取数据。
  • 缓存,在这个答案中有详细介绍

提醒

CORS 执行上述操作。它不执行以下操作:

  • 阻止服务器处理请求 - 这就是身份验证和 CSRF 预防的目的。
  • 停止欺骗 Origin 标头 - 这仅适用于合作的浏览器。作为攻击者,您通常无权访问用户正在使用的浏览器。由于标头可能被欺骗,因此出于安全考虑,服务器不应使用其中的数据。(这就是为什么当通过 CURL/Postman/Insomnia 等工具测试浏览器 API 时,您需要检查 CORS 标头是否通过,因为它们接受所有响应并且 CORS 策略永远不会应用。)