Mar*_*per 8 architecture amazon-web-services cors single-page-application
我想构建一个单页应用程序(SPA),并在后端 API(REST)和前端资产(静态 vue.js 代码)分离期间注意到以下问题:
当从 API 后端以外的其他域提供 index.html 时,大多数 POST/PUT 请求都会触发 CORS 预检请求。
我做了一些研究,发现博客文章 [1][2] 讨论了这个问题 - 没有给出实际的解决方案。某些标头(例如,授权标头和具有application/json值的 Content-Type 标头)不允许作为 cors-safelisted-request-header。因此,POST/PUT 请求会触发 CORS 预检请求。这是不可接受的,因为它增加了大量的延迟。
如果两个域都属于同一实体,是否可以避免这些预检请求?
我做了一些关于如何避免前端和后端之间的 CORS 请求的研究。该解决方案需要从与 REST API 后端相同的域提供 index.html 文件(请参阅下面的示例)。我想知道不使用单独的域是否是避免 SPA 的 CORS 请求的唯一解决方案。
[1] https://www.freecodecamp.org/news/the-terrible-performance-cost-of-cors-api-on-the-single-page-application-spa-6fcf71e50147/
[2] https:// developer.akamai.com/blog/2015/08/17/solving-options-performance-issue-spas
如何避免单页应用程序中的 CORS 预检请求?
首先,您不能“避免”标准中的某些内容。其次,这个问题表述有误,因为 SPA 本身可以使用或不使用 CORS。这完全取决于您的设置/设计。如果您想避免预检,请不要从其他来源请求资源。
如果两个域都归同一个实体所有,是否可以避免这些预检请求?
不。
站点所有权与 CORS 无关。跨域资源共享意味着您要在不同的源之间共享资源。不一定在不同域之间。Origin 既不是实体也不是所有者。Origin 只是 URL 的一部分。
最好的解决方案是完全避免引入 CORS 问题并始终坚持同源。您认为应该将后端 API 与具有不同来源的前端资产分开的假设是不正确的。
在您的设置中引入多个源和域会增加更多的问题,而不是它解决的问题。理想情况下,您的整个设置应该隐藏在连接客户端之外,并简化为单个域和源。
你想要的设置
-> static file server
CDN -> Load balancer -> api server
-> api server
-> ...
Run Code Online (Sandbox Code Playgroud)
示例配置
使用您的负载均衡器及其 ACL 规则。告诉它把所有流量路由到它应该去的地方。我将使用haproxy作为示例,因为这就是我使用的,并且因为据我所知,这在软件负载平衡解决方案方面几乎是行业标准。
这不是整个配置,只是与路由流量相关的部分。
-> static file server
CDN -> Load balancer -> api server
-> api server
-> ...
Run Code Online (Sandbox Code Playgroud)
那里没有太多选择。
最简单的解决方案是从与 API 相同的域提供 html 和资产。
第二个选项是仅使用 cors-safelisted-request-header 标头。
我注意到的是:
可以用标题Content-Type替换标题Accept。这个标题没问题。
如果您正在执行 XHR 请求,则可以省略Authentication标头,而是通过将withCredentialsXHR 请求的字段设置为 true 来自动添加身份验证信息。VanillaJS 示例:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.example.org/api/whatever', true);
xhr.withCredentials = true;
xhr.send();
Run Code Online (Sandbox Code Playgroud)
如果您使用任何其他 XHR 客户端,请查阅文档是否可以设置该选项。
另一种选择是使用 cookie 和服务器端会话进行身份验证。当您使用 AWS 时,AWS Cognito 可能是一个选择。
如果正在使用的更多标头不是列入安全列表的 CORS 标头,则必须删除它们。
| 归档时间: |
|
| 查看次数: |
2099 次 |
| 最近记录: |