我正在使用rails-api构建一个公共的json api.
我想回应OPTIONS HTTP方法以利用跨源资源共享.
我这样做:
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
Run Code Online (Sandbox Code Playgroud)
它可以工作,但有些URL不支持所有HTTP方法.在那些情况下,我撒谎.
我不想为每个URL配置Access-Control-Allow-Methods.
有没有办法根据我的路线响应Access-Control-Allow-Methods?
我正在开发一个Web应用程序.它使用基本身份验证.它必须处理OPTIONS请求.这些是Web浏览器预检请求以及来自WebDAV客户端的功能支持请求.
据我所知,OPTIONS请求必须在不请求身份验证的情况下处理(即我的服务器不应该响应401 Unauthorized),它必须给出如下响应:
OPTIONS https://localhost:44305/path/file.ext HTTP/1.1
Connection: Keep-Alive
User-Agent: some app
Host: localhost:44305
HTTP/1.1 200 OK
Content-Length: 0
DAV: 1, 2, 3
Date: Fri, 27 Dec 2013 17:10:21 GMT
Run Code Online (Sandbox Code Playgroud)
我的问题是:我是否应该始终对OPTIONS请求提供相同的响应,无论URL是什么,还是应该依赖于URL.
例如,如果找不到上例中的file.ext,我应该回复'404 Not found'还是'200 OK'?
我有一个ASP.NET Web API,由三个不同的SPA调用.我正在为Web API使用Windows身份验证.我最初尝试在Web.config中配置CORS,如下所示:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:63342" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
Run Code Online (Sandbox Code Playgroud)
这导致了这个预检问题:
Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin (...) is therefore not allowed access.
Run Code Online (Sandbox Code Playgroud)
我通过在Global.asax.cs中添加以下方法解决了:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法适用于单一SPA.我以为我可以去Web.config并添加其他类似的来源:
<add name="Access-Control-Allow-Origin" value="http://localhost:63342,http://localhost:63347,http://localhost:63345/>
Run Code Online (Sandbox Code Playgroud)
但显然这是不允许的.这产生了以下错误:
The 'Access-Control-Allow-Origin' header contains …Run Code Online (Sandbox Code Playgroud) 授权标头不随 HTTP OPTIONS 请求一起发送。我只想在请求为 OPTIONS 时禁用此身份验证,并为其他请求保留此身份验证。这是我目前拥有的相关配置代码。似乎无法理解为什么它不起作用。我总是在 OPTIONS 请求中收到 401 未经授权的错误。
location ~ /foo/bar
{
if ($request_method = OPTIONS) {
set $auth_basic "off";
}
if ($request_method != OPTIONS)
{
set $auth_basic "Resctricted";
set $auth_basic_user_file /var/www/.htpasswd;
}
auth_basic $auth_basic;
auth_basic_user_file $auth_basic_user_file;
}
Run Code Online (Sandbox Code Playgroud) 我是NestJS的新手,在我的网络应用尝试查询的每条路线上,它都在OPTIONS请求上失败,得到:
{"statusCode":404,"error":"Not Found","message":"无法选择/验证"}
但尝试直接GET或POST请求工作正常.
根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2,有关HTTP OPTIONS请求的唯一回复是200.但是,似乎有这样的情况,例如content-length为0表示204更合适.HTTP OPTIONS请求是否适合返回204?
如果HTTP资源无法使用给定的HTTP方法处理请求,则它应发送Allow标头以列出允许的HTTP方法.使用Allow标头获得响应的另一种可能性是使用该OPTIONS方法发送请求.
我想知道Allow标题是否应该包含OPTIONS方法本身.
例:
Allow: GET, PUT, DELETE, OPTIONS
Run Code Online (Sandbox Code Playgroud)
要么
Allow: GET, PUT, DELETE
Run Code Online (Sandbox Code Playgroud)
什么是正确的?
我注意到Mozilla HTTP响应代码文档说明了这一点
方法PUT,DELETE和OPTIONS永远不会产生200 OK响应.
但是,它并不清楚实际应该使用什么样的响应.我最好的猜测是204:
204:没有内容
没有要为此请求发送的内容,但标头可能很有用.用户代理可以使用新资源更新其资源的缓存标头.
任何人都可以评论这是否是用于响应OPTIONS请求的正确代码?
我已经开始设计一个API,并决定让它符合REST/HATEOAS.API的切入点应该是什么?
这似乎是一个常见的,GET /但从我所读到的,它可能在逻辑上更有意义使用OPTIONS /,因为实际上没有/用于检索的资源.
我在这里给出了两个例子,使用JSON的HAL语法作为超媒体格式.
请求:
GET / HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)
响应:
HTTP/1.1 200 OK
Date: …
Content-Type: application/json;charset=utf-8
Content-Length: 143
{
"_links": {
"self": {
"href": "/"
},
"penguins": {
"href": "/penguins"
}
}
}
Run Code Online (Sandbox Code Playgroud)
请求:
OPTIONS / HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)
响应:
HTTP/1.1 200 OK
Date: …
Allow: OPTIONS
Content-Type: application/json;charset=utf-8
Content-Length: 143
{
"_links": {
"self": {
"href": "/"
},
"penguins": {
"href": "/penguins"
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在开发一个使用嵌入式Jetty的项目(不幸的是我只是"继承"了项目的服务器端,并且对Jetty及其配置的使用不是很熟悉).
刚出现一个奇怪的案例 - 我会尽力描述:
基于Web的UI(使用AngularJS,来自不同的域,因此使用CORS)发送POST请求以更改服务器上某些内容的状态.这在过去的某个时刻起作用(它可能是大约一个月前使用过的).
昨天这停止了工作.检查REST调用,我看到首先发出OPTIONS请求.POST的内容类型是application/json,所以基于我读过的内容,这是正确的.我不确定为什么之前没有发送过 - 有可能该公司最近更新了Chrome版本,旧版本没有发送预检请求,但这只是猜测.在任何情况下,我认为这是我的应用程序中为JetS配置CORS的相关代码:
FilterHolder holder = new FilterHolder(new CrossOriginFilter());
holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
appHandler.addFilter(holder, "/*", EnumSet.of(DispatcherType.REQUEST));
Run Code Online (Sandbox Code Playgroud)
一切都适用于POST请求.我可以通过使用--disable-web-security标志启动Chrome来验证这一点.没有发送OPTIONS请求,并且POST正常工作.
我的想法是,因为它适用于POST,它不是授权或安全问题 - 它只是没有正确配置Jetty来处理预检请求(它只返回401).
我找不到很多关于嵌入式Jetty的文档,以及哪些CrossOriginFilter常量在调用setInitParameter时用作属性键(而且,因为该方法调用的第二个参数是一个String,我真的不知道如何格式化值).
我应该在CrossOriginFilter上设置哪些参数来处理OPTIONS请求?如果我上面说过任何错误或做出任何错误的假设,请纠正我!我对这方面的经验非常有限.