我正在构建一个利用CORS的REST应用程序。每个REST调用都是不同的,我发现获取预检OPTIONS调用会产生大量开销。有没有一种方法可以缓存和应用预检OPTIONS结果,以便对同一域的任何后续调用都可以使用缓存的响应?
我正在构建一个利用CORS的REST应用程序。每个REST调用都是不同的,我发现获取预检OPTIONS调用会产生大量开销。有没有一种方法可以缓存和应用预检OPTIONS结果,以便对同一域的任何后续调用都可以使用缓存的响应?
Answers:
预检只能应用于请求,而不能应用于整个域。我在邮件列表中提出了同样的问题,并且存在安全隐患。这是整个主题:http : //lists.w3.org/Archives/Public/public-webapps/2012AprJun/0228.html
如果您想限制预检请求的数量,则需要考虑一些事项。首先请注意,基于WebKit / Blink的浏览器将最大预检缓存设置为10分钟:
https://github.com/WebKit/webkit/blob/master/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp https://chromium.googlesource.com/chromium/blink/+/master/Source/core/loader/CrossOriginPreflightResultCache .cpp
(我不确定其他浏览器是否适用)。因此,尽管应始终设置Access-Control-Max-Age标头,但最大值为10分钟。
接下来要注意的是,不可能避免对PUT / DELETE请求进行预检。因此,对API的更新/删除每10分钟至少需要进行一次飞行前检查。
在GET / POST上,请尽可能避免使用自定义标头,因为它们仍然会触发预检。如果您的API返回JSON,请注意Content-Type为“ application / json”也会触发预检。
如果您愿意改变API的“ RESTful”程度,则可以尝试更多方法。一种是使用不需要预检的Content-Type,例如“文本/纯文本”。自定义标题始终会触发预检,因此,如果您有任何自定义标题,则可以将其移至查询参数中。在最末端,您可以使用JSON-RPC之类的协议,其中所有请求都向单个端点发出。
老实说,由于浏览器的预检缓存限制为10分钟,并且REST的资源网址如此,因此预检缓存相当无用。在长期运行的应用程序中,您几乎没有什么可以限制飞行前检查的。我希望CORS规范的作者将来会尝试解决这个问题。
Access-Control-Max-Age
存在且浏览器看到了完全相同的URL,否则浏览器将触发OPTIONS请求。之前的浏览器,并且它在所指定的期限内,Access-Control-Max-Age
并且所涉及的浏览器不会缩短值(Webkit,Firefox)。如果您摆脱了自定义标头,并将其移至url,浏览器将不会发送OPTIONS请求。胜利!
尝试使用xDomain
对于我来说,使用angular或jQuery进行设置非常简单。在您的应用服务器上,按照以下链接中的帮助所述添加proxy.html。在您的“客户端”和中提琴上添加一些引用js文件的标签,无需再进行飞行前检查。它将包装在iframe中,以避免需要进行cors检查。