我正在构建一个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网站上-你可以进行同源请求,不需要任何选项请求:)
其他回答
OPTIONS请求是web浏览器的一个特性,所以要禁用它并不容易。但我找到了用代理转移的方法。如果服务端点还不能处理CORS/OPTIONS,可能还在开发中,或者配置错误,那么它就很有用。
步骤:
使用工具(nginx, YARP,…)为这些请求设置反向代理。 创建一个端点来处理OPTIONS请求。创建一个普通的空端点可能更容易,并确保它能很好地处理CORS。 为代理配置两组规则。一种是将所有OPTIONS请求路由到上面的虚拟端点。另一个是将所有其他请求路由到实际的问题端点。 更新网站以使用代理代替。
基本上这种方法是欺骗浏览器,选项请求工作。考虑到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配置。
在使用代理拦截请求并写入适当的标头的情况下,可以解决这个问题。 在Varnish的特殊情况下,这些将是规则:
if (req.http.host == "CUSTOM_URL" ) {
set resp.http.Access-Control-Allow-Origin = "*";
if (req.method == "OPTIONS") {
set resp.http.Access-Control-Max-Age = "1728000";
set resp.http.Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, PATCH, OPTIONS";
set resp.http.Access-Control-Allow-Headers = "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since";
set resp.http.Content-Length = "0";
set resp.http.Content-Type = "text/plain charset=UTF-8";
set resp.status = 204;
}
}
关于飞行前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
我已经解决了这个问题。
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应用程序将在同一台机器上生产,所以没有选项,但开发是我的本地。
推荐文章
- 什么是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“期望失败。”