如何将CORS飞行前缓存应用于整个域

如何将CORS飞行前缓存应用于整个域,cors,Cors,我正在构建一个使用CORS的REST应用程序。每个REST调用都是不同的,我发现在获取飞行前选项调用时有很大的开销。是否有办法缓存和应用飞行前选项结果,以便对同一域的任何后续调用都使用缓存的响应?飞行前选项只能应用于请求,而不能应用于整个域。我在邮件列表上提出了同样的问题,其中涉及到安全问题。以下是整个线程: 如果你想限制飞行前请求的数量,有一些事情要考虑。首先请注意,基于WebKit/Blink的浏览器将最大飞行前缓存设置为10分钟: (我不确定这是否适用于其他浏览器)。因此,虽然您应该始

我正在构建一个使用CORS的REST应用程序。每个REST调用都是不同的,我发现在获取飞行前选项调用时有很大的开销。是否有办法缓存和应用飞行前选项结果,以便对同一域的任何后续调用都使用缓存的响应?

飞行前选项只能应用于请求,而不能应用于整个域。我在邮件列表上提出了同样的问题,其中涉及到安全问题。以下是整个线程:

如果你想限制飞行前请求的数量,有一些事情要考虑。首先请注意,基于WebKit/Blink的浏览器将最大飞行前缓存设置为10分钟:

(我不确定这是否适用于其他浏览器)。因此,虽然您应该始终设置访问控制最大年龄标头,但最大值为10分钟

接下来要注意的是,不可能避免PUT/DELETE请求的预飞行。因此,对API的更新/删除至少需要每10分钟进行一次预飞行

在GET/POST上,尽可能避免使用自定义标题,因为这些标题仍然会触发预飞行。如果API返回JSON,请注意,“application/JSON”的内容类型也会触发预飞行

如果您愿意改变API的“RESTful”程度,那么您还可以尝试其他一些方法。一种是使用不需要预飞行的内容类型,如“text/plain”。自定义标题总是触发预提示,所以如果您有任何自定义标题,可以将它们移动到查询参数中。在极端情况下,您可以使用类似JSON-RPC的协议,其中所有请求都向单个端点发出

老实说,由于浏览器的飞行前缓存限制为10分钟,以及REST的资源URL,飞行前缓存是相当无用的。在长时间运行的应用程序中,您几乎无法限制预飞行。我希望CORS规范的作者将来会尝试解决这个问题。

尝试使用xDomain

如果使用angular或jQuery,对我来说设置起来非常简单。在应用服务器上,添加proxy.html,如下面链接的帮助中所述。在你的“客户机”和viola上添加一些指向js文件的标签,不再进行预飞行。这将包裹在iframe中,以避免需要进行cors检查


一种方法是,您可以将所有API调用指向与前端相同的域。在前端服务器上设置nginx,以便仅将API调用转发到API服务器。这将删除所有飞行前调用。

问题的附录:如果无法为较小范围缓存飞行前请求,那么在RESTful应用程序中限制飞行前请求数量的最佳方法是什么?反向代理,检查nginx,将允许您避免CORS飞行前惩罚。简单的map/api->api.site.com有一个很好的流程图,帮助我了解在什么情况下会进行飞行前呼叫(以及如何避免)。@uglymunky我将澄清这一部分。飞行前缓存的密钥基于源/url对,其中url是完整的请求url。我的意思是,如果你有一个自定义的头,它总是会触发一个预飞行,即使是在GET请求上。但是,如果您将该自定义标头移动到查询参数中,则GET/POST请求将不会有预飞行。@monsur Hi在聚会上迟到了一点,但不知道您是否可以提出建议。。我当前正在向我的API传递一个授权头(例如“Basic[base64 encoded string]”),其中包含所有请求。飞行前的请求主要阻碍了应用程序的性能。如果我移动到一个基于令牌的身份验证系统(将令牌作为URL中的QS参数),并完全摆脱自定义标题,这会不会是一种避免get和POST的可怕选项请求的方法(我同意有一些用于PUT和DELETE)?@adaam应该可以做到这一点。我刚刚在Firefox和Chrome中完成了一些测试,以更好地了解其行为,并可以分享以下信息:如果您的自定义头存在,浏览器将触发选项请求,除非存在
Access Control Max Age
,并且之前浏览器已看到完全相同的URL,并且该URL在
Access Control Max Age
指定的时间内,并且相关浏览器未缩短该值(Webkit、Firefox)。如果删除自定义标题并将其移动到url中,浏览器将不会发送选项请求。胜利!我喜欢他们停止回复你的电子邮件。在您的回答中,内容类型限制仅在发送数据时相关,而在接收数据时不相关,因此服务器返回任意内容类型标题时没有问题。