我正在构建一个web API。我发现每当我使用Chrome POST, GET到我的API,总是有一个选项请求发送之前的真正的请求,这是相当恼人的。目前,我让服务器忽略任何OPTIONS请求。现在我的问题是,发送一个OPTIONS请求来增加服务器的负载有什么好处呢?有没有办法完全停止浏览器发送OPTIONS请求?
当前回答
我以前用过的一个解决方案——假设你的网站在mydomain.com上,你需要向foreigndomain.com发送一个ajax请求
配置IIS重写从您的域到外部域-例如。
<rewrite>
<rules>
<rule name="ForeignRewrite" stopProcessing="true">
<match url="^api/v1/(.*)$" />
<action type="Rewrite" url="https://foreigndomain.com/{R:1}" />
</rule>
</rules>
</rewrite>
在你的mydomain.com网站上-你可以进行同源请求,不需要任何选项请求:)
其他回答
已经讨论过这个问题,下面是我对这个问题的结论和我的解决方案。
根据CORS策略(强烈建议您阅读它),如果浏览器认为它需要停止发送OPTIONS请求,您不能仅仅强制浏览器停止发送OPTIONS请求。
有两种方法可以解决这个问题:
确保你的请求是“简单请求” 设置OPTIONS请求的Access-Control-Max-Age
简单的请求
一个简单的跨站点请求是一个满足以下所有条件的请求:
唯一允许的方法是:
得到 头 帖子
除了由用户代理(例如Connection, user - agent等)自动设置的头信息外,允许手动设置的头信息有:
接受 接收语言 内容语言 内容类型
Content-Type头唯一允许的值是:
应用程序/ x-www-form-urlencoded 多部分/格式 文本/平原
简单的请求不会引起飞行前选项请求。
为OPTIONS检查设置缓存
您可以为OPTIONS请求设置Access-Control-Max-Age,以便它在过期之前不会再次检查权限。
Access-Control-Max-Age给出了在不发送另一个preflight请求的情况下,对preflight请求的响应可以缓存的时间(以秒为单位)。
限制指出
对于Chrome, Access-Control-Max-Age的最大秒数是600,也就是10分钟,根据Chrome源代码 Access-Control-Max-Age每次只对一个资源有效,例如URL路径相同的GET请求,但不同的查询将被视为不同的资源。因此,对第二个资源的请求仍然会触发预飞行请求。
是的,有可能避免期权请求。选项请求是一个飞行前请求,当你发送(post)任何数据到另一个域。这是浏览器安全问题。但是我们可以使用另一种技术:iframe传输层。我强烈建议您忘记任何CORS配置,并使用现成的解决方案,它将在任何地方工作。
看看这里: https://github.com/jpillora/xdomain
工作示例: http://jpillora.com/xdomain/
在花了一整天半的时间试图解决类似的问题后,我发现这与IIS有关。
我的Web API项目是这样建立的:
// WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
//...
}
我在网上没有CORS特定的配置选项。配置>系统。webServer节点,就像我在很多帖子中看到的那样
全局中没有特定于CORS的代码。Asax或在控制器中作为装饰器
问题在于应用程序池设置。
托管管道模式被设置为经典(更改为集成),标识被设置为网络服务(更改为ApplicationPoolIdentity)
更改这些设置(并刷新应用程序池)为我解决了这个问题。
我已经解决了这个问题。
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 -引入飞行前请求的动机是什么?
要禁用OPTIONS请求,ajax请求必须满足以下条件:
请求不设置自定义HTTP报头,如'application/xml'或'application/json'等 请求方法必须是GET、HEAD或POST中的一个。如果是POST,内容类型应该是application/x-www-form-urlencoded、multipart/form-data或text/plain
参考: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
推荐文章
- 如何使HTTP请求在PHP和不等待响应
- PATCH和PUT请求的主要区别是什么?
- Access-Control-Allow-Origin不允许Origin < Origin >
- 我可以把我所有的http://链接都改成//吗?
- URL为AJAX请求编码一个jQuery字符串
- 如何获得跨源资源共享(CORS)后请求工作
- 编译System.Net.HttpClient的查询字符串
- 摘要认证和基本认证的区别是什么?
- Axios -删除请求与请求体和头?
- 在Firebase的云功能中启用CORS
- 如何在http获取请求设置报头?
- 如何使用Ruby on Rails进行HTTP请求?
- REST API最佳实践:查询字符串中的参数vs请求体中的参数
- Access-Control-Allow-Credentials报头到底做什么?
- Express.js中的res.send和res.json的区别