我正在构建一个web API。我发现每当我使用Chrome POST, GET到我的API,总是有一个选项请求发送之前的真正的请求,这是相当恼人的。目前,我让服务器忽略任何OPTIONS请求。现在我的问题是,发送一个OPTIONS请求来增加服务器的负载有什么好处呢?有没有办法完全停止浏览器发送OPTIONS请求?


当前回答

在花了一整天半的时间试图解决类似的问题后,我发现这与IIS有关。

我的Web API项目是这样建立的:

// WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
    var cors = new EnableCorsAttribute("*", "*", "*");
    config.EnableCors(cors);
    //...
}

我在网上没有CORS特定的配置选项。配置>系统。webServer节点,就像我在很多帖子中看到的那样

全局中没有特定于CORS的代码。Asax或在控制器中作为装饰器

问题在于应用程序池设置。

托管管道模式被设置为经典(更改为集成),标识被设置为网络服务(更改为ApplicationPoolIdentity)

更改这些设置(并刷新应用程序池)为我解决了这个问题。

其他回答

当您打开调试控制台并打开禁用缓存选项时,将始终发送预飞行请求(即在每个请求之前)。如果不禁用缓存,预运行请求将只发送一次(每个服务器)。

编辑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

CORS OPTIONS请求仅在某些情况下被触发,如MDN文档中所解释的:

Some requests don’t trigger a CORS preflight. Those are called “simple requests” in this article, though the Fetch spec (which defines CORS) doesn’t use that term. A request that doesn’t trigger a CORS preflight—a so-called “simple request”—is one that meets all the following conditions: The only allowed methods are: GET HEAD POST Apart from the headers set automatically by the user agent (for example, Connection, User-Agent, or any of the other headers with names defined in the Fetch spec as a “forbidden header name”), the only headers which are allowed to be manually set are those which the Fetch spec defines as being a “CORS-safelisted request-header”, which are: Accept Accept-Language Content-Language Content-Type (but note the additional requirements below) DPR Downlink Save-Data Viewport-Width Width The only allowed values for the Content-Type header are: application/x-www-form-urlencoded multipart/form-data text/plain No event listeners are registered on any XMLHttpRequestUpload object used in the request; these are accessed using the XMLHttpRequest.upload property. No ReadableStream object is used in the request.

不能,但可以使用JSONP避免CORS。

关于飞行前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

是的,有可能避免期权请求。选项请求是一个飞行前请求,当你发送(post)任何数据到另一个域。这是浏览器安全问题。但是我们可以使用另一种技术:iframe传输层。我强烈建议您忘记任何CORS配置,并使用现成的解决方案,它将在任何地方工作。

看看这里: https://github.com/jpillora/xdomain

工作示例: http://jpillora.com/xdomain/