获取API;如果响应为不透明,为什么要使用“无心”模式?

时间:2018-09-29 15:34:59

标签: cors fetch fetch-api

我读了this questionthis question。前者只解释“无心”与“相同起源”;后者建议因为不透明响应(Javascript无法读取/做任何有用的事情),因此“ no-cors”不可用:

  

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

有人可以建议在这些“有限情况”下,我们希望使用“无底线”的示例是什么(即使响应是不透明的)?

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

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

我的想法是否有效?有人可以推荐其他可能性/用例/“无条件使用”的示例吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

请注意,上面还有第0步。这是一个选项,发送“飞行前检查”以检查是否通过了请求,从而允许页面查看结果?如果没有,则他们认为发送请求毫无意义-但这是一个假设。

现在要解决问题

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策略。)