81

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

4

3 回答 3

111

预检只能应用于请求,不能应用于整个域。我在邮件列表中提出了同样的问题,并且存在安全问题。这是整个线程: 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,请注意“application/json”的 Content-Type 也会触发预检。

如果你愿意改变你的 API 的“RESTful”程度,你可以尝试更多的东西。一种是使用不需要预检的 Content-Type,例如“text/plain”。自定义标头始终触发预检,因此如果您有任何自定义标头,您可以将它们移动到查询参数中。在极端情况下,您可以使用 JSON-RPC 之类的协议,其中所有请求都发送到单个端点。

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

于 2012-08-18T20:25:17.083 回答
6

尝试使用 xDomain

如果使用 Angular 或 jQuery,我的设置非常简单。在您的应用服务器上,按照以下链接的帮助中的说明添加 proxy.html。在您的“客户端”和中提琴上添加一些引用 js 文件的标签,不再进行预检。这包含在 iframe 中以避免需要进行 cors 检查。

https://github.com/jpilora/xdomain

于 2015-11-20T14:55:26.310 回答
1

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

于 2018-02-26T05:08:28.330 回答