我正在构建一个web API。我发现每当我使用Chrome POST, GET到我的API,总是有一个选项请求发送之前的真正的请求,这是相当恼人的。目前,我让服务器忽略任何OPTIONS请求。现在我的问题是,发送一个OPTIONS请求来增加服务器的负载有什么好处呢?有没有办法完全停止浏览器发送OPTIONS请求?
当前回答
对于一个理解它存在的原因,但需要访问一个没有认证就不能处理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),那么你只需要启用开发人员菜单,并从开发菜单中选择“禁用跨源限制”。
其他回答
编辑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。
已经讨论过这个问题,下面是我对这个问题的结论和我的解决方案。
根据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请求,但不同的查询将被视为不同的资源。因此,对第二个资源的请求仍然会触发预飞行请求。
对我有用的是导入“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请求是web浏览器的一个特性,所以要禁用它并不容易。但我找到了用代理转移的方法。如果服务端点还不能处理CORS/OPTIONS,可能还在开发中,或者配置错误,那么它就很有用。
步骤:
使用工具(nginx, YARP,…)为这些请求设置反向代理。 创建一个端点来处理OPTIONS请求。创建一个普通的空端点可能更容易,并确保它能很好地处理CORS。 为代理配置两组规则。一种是将所有OPTIONS请求路由到上面的虚拟端点。另一个是将所有其他请求路由到实际的问题端点。 更新网站以使用代理代替。
基本上这种方法是欺骗浏览器,选项请求工作。考虑到CORS并不是为了加强安全,而是为了放松同源政策,我希望这招能管用一段时间。:)
推荐文章
- 什么是HTTP“主机”报头?
- XMLHttpRequest Origin null不允许Access-Control-Allow-Origin for file:/// to file:///(无服务器)
- 哪个HTTP状态代码表示“尚未准备好,稍后再试”?
- 如何阻止恶意代码欺骗“Origin”报头来利用CORS?
- 为什么说“HTTP是无状态协议”?
- 我需要HTTP GET请求的内容类型报头吗?
- 如何让Chrome允许混合内容?
- 正确的方式删除cookies服务器端
- REST DELETE真的是幂等的吗?
- 什么是不透明的回应,它的目的是什么?
- 了解Chrome网络日志“停滞”状态
- 用户代理字符串可以有多大?
- 什么是接受* HTTP报头q=0.5 ?
- HTTP状态码200(缓存)和状态码304之间有什么区别?
- HTTP POST返回错误:417“期望失败。”