我正在构建一个Web API。我发现每当我使用Chrome进行POST和GET请求到我的API时,总会在真正的请求之前发送一个OPTIONS请求,这相当令人烦恼。目前,我让服务器忽略任何OPTIONS请求。现在我的问题是,有什么好方法可以发送OPTIONS请求以增加服务器的负载?是否有任何方法完全停止浏览器发送OPTIONS请求?
编辑 2018-09-13: 在本回答的末尾添加了一些关于这个预检请求及如何避免它的详细信息。
OPTIONS
请求在跨域资源共享(CORS)
中被称为预检请求
。
在特定情况下,当你在不同的源之间进行请求时,它们是必需的。
这个预检请求是某些浏览器作为安全措施而发出的,以确保正在进行的请求是由服务器信任的。 这意味着服务器理解请求中发送的方法、来源和标头是安全的并可以采取行动。
每当你尝试进行跨源请求时,你的服务器不应该忽略而是处理这些请求。
可以在这里找到一个很好的资源 http://enable-cors.org/
处理这些请求的一种方法是确保对于任何带有OPTIONS
方法的路径,服务器都会发送一个带有以下标头的响应:
Access-Control-Allow-Origin: *
这将告诉浏览器,服务器愿意来自任何来源的请求作出回应。
如需了解如何为您的服务器添加CORS支持的更多信息,请参阅以下流程图。
http://www.html5rocks.com/static/images/cors_server_flowchart.png
编辑于2018-09-13
如MDN文档所述,CORS OPTIONS
请求仅在某些情况下触发:
curl
命令调用API,它可以正常工作,但是从Chrome运行时出现错误,这是怎么回事? - SuperUberDuper我遇到了这个问题,以下是我的结论和解决方案。
根据CORS策略(强烈推荐您了解一下),如果浏览器认为有必要发送OPTIONS请求,那么您不能强制停止它发送该请求。
有两种方法可以解决这个问题:
Access-Control-Max-Age
简单跨站点请求是指同时满足以下所有条件的请求:
只允许以下方法:
除了用户代理自动设置的标题之外(例如Connection、User-Agent等),只允许手动设置以下标题:
Content-Type标头的唯一允许值为:
简单请求不会引起预检OPTIONS请求。
您可以为OPTIONS请求设置Access-Control-Max-Age
,以便在过期之前不会再次检查权限。
Access-Control-Max-Age给出了预检请求响应的缓存时间(以秒为单位),在此期间无需发送另一个预检请求。
Access-Control-Max-Age
的最大秒数为600
,即10分钟。Access-Control-Max-Age
每次只适用于一个资源,例如具有相同URL路径但不同查询的GET
请求将被视为不同的资源。因此,对第二个资源的请求仍将触发预检请求。Access-Control-Max-Age
。这是关键之处,它有助于避免过多的预检请求。 - Idris Mokhtarzadaapplication/json
会使你的请求变得不 "simple"(从而触发CORS)而回避它。浏览器在执行它的工作。请设置服务器返回一个类似于 Access-Control-Max-Age: 86400
的头部,浏览器将不会在24小时内重新发送OPTIONS请求。 - colm.anseoapplication/x-www-form-urlencoded
、multipart/form-data
或 text/plain
之一Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
application/xml
或application/json
不是“自定义HTTP头”。头本身应该是Content-Type
,将该头称为“自定义”会引起误解。 - Leo Correa是的,可以避免Options请求。当您向另一个域发送(发布)任何数据时,Options请求是预检请求。这是浏览器安全问题。但是我们可以使用另一种技术:iframe传输层。我强烈建议您忘记任何CORS配置并使用现成的解决方案,它可以在任何地方使用。
请看这里: https://github.com/jpillora/xdomain
以及工作示例: http://jpillora.com/xdomain/
对于一个理解API存在原因但需要访问不支持不带认证的OPTIONS调用的API的开发人员,我需要一个临时的解决方案,以便在API所有者添加适当的SPA CORS支持或我启动代理API之前可以在本地开发。
我发现您可以在Mac上的Safari和Chrome中禁用CORS。
Chrome:退出Chrome,打开终端并粘贴此命令:open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Safari:在Safari中禁用同源策略
如果要在Safari(我的版本是9.1.1)中禁用同源策略,则只需启用开发人员菜单,然后从“开发”菜单中选择“禁用跨域限制”即可。
OPTIONS
请求将使用此标头缓存的事实非常不透明。 - joshperry我已经解决了这个问题,方法如下。
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS' && ENV == 'devel') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header("HTTP/1.1 200 OK");
die();
}
这只是为了开发使用。这样我可以等待9毫秒和500毫秒而不是8秒和500毫秒。我可以这样做是因为生产环境中JS应用程序将在与生产环境相同的机器上运行,因此不会有OPTIONS
,但开发环境是我的本地环境。
你不能直接解决CORS问题,但可以使用JSONP避免它。
OPTIONS请求是Web浏览器的一个功能,因此很难禁用它。但我找到了一种使用代理进行重定向的方法。这在服务端点无法处理CORS/OPTIONS请求的情况下非常有用,可能仍在开发中或配置不正确。
步骤:
基本上,这种方法是欺骗浏览器认为OPTIONS请求有效。考虑到CORS并不是为了增强安全性,而是为了放宽同源策略,我希望这个技巧能够持续一段时间。 :)