【问题标题】:Fetch API; why use the "no-cors" mode if the response is Opaque?获取 API;如果响应是不透明的,为什么要使用“no-cors”模式?
【发布时间】:2019-03-05 07:27:52
【问题描述】:

我读过 this questionthis question 。前者只解释了“no-cors”与“same-origin”;后者建议“no-cors”因为不透明响应(Javascript 无法读取/执行任何有用的操作)而无用:

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

有人可以建议这些“有限情况”的例子有哪些我们想使用“no-cors”(即使响应是不透明的?)

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

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

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

【问题讨论】:

  • stackoverflow.com/a/39109790/441757 上查看答案。主要情况是(1)当您想要对资源做的唯一事情是缓存它时,以及(2)当您想要将资源用作<script><link rel="stylesheet">、@987654328 的内容时文档中的@、<video><audio><object><embed><iframe> 元素(之所以有效,是因为这些元素允许跨域嵌入资源)。
  • 就缓存案例而言,正如stackoverflow.com/a/39109790/441757 中所解释的那样,实际上适用的场景是当您使用 Service Worker 时,在这种情况下,相关的特定 API 是缓存存储APIdeveloper.mozilla.org/en-US/docs/Web/API/CacheStorage
  • 非常感谢;另一个答案很好,但是您在此处的澄清/总结很有帮助且具体。

标签: cors fetch fetch-api


【解决方案1】:

请记住,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,以便在我真正需要时读取数据。
  • Caching, detailed in this answer

提醒

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

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

【讨论】:

  • 跳过预检OPTION 请求是一个显着的区别!感谢您指出这一点。
猜你喜欢
  • 2021-08-25
  • 2016-07-17
  • 2018-08-19
  • 2022-10-14
  • 2015-12-26
  • 2020-02-17
相关资源
最近更新 更多