一般:
Request URL:x/site.php
Request Method:OPTIONS
Status Code:302 Found
Remote Address:x.x.x.x:80
响应标题:
view source
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Origin:*
Access-Control-Max-Age:300
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Length:0
Content-Type:text/html; charset=UTF-8
Date:Thu, 02 Mar 2017 14:27:21 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Location:y
Pragma:no-cache
Server:Apache/2.4.25 (Ubuntu)
请求标题:
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:x
Origin:http://127.0.0.1:3000
Pragma:no-cache
Referer:http://127.0.0.1:3000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36
Apache virtualhost配置如下所示:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://127.0.0.1:3000"
Header set Access-Control-Allow-Origin "http://127.0.0.1"
Header set Access-Control-Max-Age "300"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
Header set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, PATCH, OPTIONS"
</IfModule>
预检请求正在跳过apache配置并直接点击我的webapp,这会进行重定向(因此302和位置:y)。
我不知道为什么apache没有处理预检请求?
答案 0 :(得分:10)
您需要更改/添加的两件事是:
Header always set
代替Header set
OPTIONS
,只需发送回200 OK
这些标题因此,为了使问题中的请求生效,这里是一个最小的(ish)配置片段:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Authorization"
Header always set Access-Control-Allow-Methods "GET, OPTIONS"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Access-Control-Max-Age "600"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
的更长解释
关于为各种Access-Control-
响应标头设置的值的一些常规说明:
Access-Control-Allow-Headers
:您必须将其设置为包含您的请求发送的任何标题名称,但 CORS-safelisted header names或所谓的{{ 3}}(由您无法在JavaScript中设置的浏览器设置的标题名称); “forbidden” header names作为其价值 - 所以你有一天可以尝试,但是还没有浏览器支持它: the spec alternatively allows the *
wildcard,Chrome bug,Firefox bug
Access-Control-Allow-Methods
:Safari bug - 但与Access-Control-Allow-Headers: *
一样,没有任何浏览器支持它
Access-Control-Expose-Headers
:您必须设置包含客户端代码需要阅读的所有响应标头Cache-Control
,Content-Language
,{{1} },Content-Type
,Expires
和Last-Modified
- 默认情况下会曝光(许多人忘记设置此内容并最终感到困惑,因为他们无法读取特定值的值响应标题);再次the spec alternatively allows the *
wildcard在这里,但没有浏览器支持它
Pragma
:Chrome的上限为Access-Control-Max-Age
(10分钟)the spec alternatively allows the *
wildcard,因此设置较高的值没有意义它不是那样的(Firefox可能会尊重它,但如果你把它设置得更高,Chrome会把它限制在10分钟,Safari会将它限制在 5 分钟)
那么,关于问题中显示的特定请求,这里有一些具体的注释:
您的请求已600
,因此在您的Apache配置中,也可以在Access-Control-Request-Headers:authorization
响应标头中添加Authorization
。
Access-Control-Allow-Headers
是浏览器设置的“禁止”标头名称,Origin
是CORS安全标头名称,因此您无需将其包含在{{1}中}}
您的请求不会发送Accept
,因此响应中的Access-Control-Allow-Headers
不需要它(Content-Type
请求永远不需要,否则仅在类型为除Access-Control-Allow-Headers
,GET
或application/x-www-form-urlencoded
)
对于text/plain
,您的请求似乎只是multipart/form-data
,因此除非您打算同时Access-Control-Allow-Methods
/ GET
/ POST
/ PUT
请求,明确包含它们没有意义