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


当前回答

对我有用的是导入“github.com/gorilla/handlers”,然后这样使用它:

router := mux.NewRouter()
router.HandleFunc("/config", getConfig).Methods("GET")
router.HandleFunc("/config/emcServer", createEmcServers).Methods("POST")

headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})

log.Fatal(http.ListenAndServe(":" + webServicePort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))

一旦我执行了Ajax POST请求并将JSON数据附加到它,Chrome总是会添加内容类型头,这不是在我以前的AllowedHeaders配置。

其他回答

在之前的文章中已经提到过,OPTIONS请求的存在是有原因的。如果您的服务器响应时间过长(例如海外连接),您也可以让浏览器缓存飞行前请求。

让你的服务器用Access-Control-Max-Age报头来回复,对于到达同一端点的请求,preflight请求将被缓存,不再发生。

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

对我有用的是导入“github.com/gorilla/handlers”,然后这样使用它:

router := mux.NewRouter()
router.HandleFunc("/config", getConfig).Methods("GET")
router.HandleFunc("/config/emcServer", createEmcServers).Methods("POST")

headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})

log.Fatal(http.ListenAndServe(":" + webServicePort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))

一旦我执行了Ajax POST请求并将JSON数据附加到它,Chrome总是会添加内容类型头,这不是在我以前的AllowedHeaders配置。

已经讨论过这个问题,下面是我对这个问题的结论和我的解决方案。

根据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请求,但不同的查询将被视为不同的资源。因此,对第二个资源的请求仍然会触发预飞行请求。

对于一个理解它存在的原因,但需要访问一个没有认证就不能处理OPTIONS调用的API的开发人员,我需要一个临时的答案,这样我就可以在本地开发,直到API所有者添加适当的SPA CORS支持或我获得一个代理API并运行。

我发现你可以在Mac电脑的Safari和Chrome浏览器中禁用CORS。

在Chrome中禁用同源策略

Chrome:退出Chrome,打开终端并粘贴如下命令:open /Applications/谷歌\ Chrome。App——args——disable-web-security——user-data-dir

Safari:禁用Safari中的同源策略

如果你想在Safari上禁用同源策略(我有9.1.1),那么你只需要启用开发人员菜单,并从开发菜单中选择“禁用跨源限制”。