General:
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 config 看起来像这样:
<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 配置并直接访问我的 web 应用程序,它会执行重定向(因此 302 和位置:y)。
我不知道为什么 Apache 没有处理预检请求?
要完全启用 CORS 的 Apache Web 服务器,您需要将其配置为如下所示:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Authorization"
Header always set Access-Control-Allow-Methods "GET"
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]
https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/的更长解释
有关为各种Access-Control-
响应标头设置哪些值的一些常规说明:
Access-Control-Allow-Headers
:您必须将其设置为包含请求发送的任何标头名称,除了CORS 安全列表的标头名称或所谓的"禁止"标头名称(由浏览器设置的标头名称,您无法在 JavaScript 中设置);规范或者允许*
通配符作为其值 - 因此您可以尝试一下,尽管某些浏览器可能还不支持它:Chrome bug,Firefox bug,Safari bug。Access-Control-Allow-Methods
:该规范允许*
通配符 - 但同样,与Access-Control-Allow-Headers: *
一样,某些浏览器可能还不支持它。Access-Control-Expose-Headers
:设置为包含前端代码需要读取的除Expires
、Cache-Control
、Content-Type
、Pragma
、Last-Modified
和Content-Language
之外的任何响应标头。很多人忘记设置它,最终对为什么他们无法读取特定响应标头的值感到困惑)。同样,规范在这里允许*
通配符,但某些浏览器可能还不支持它。Access-Control-Max-Age
:Chrome 的硬编码上限为600
(10 分钟),因此没有必要为其设置比这更高的值(如果您将其设置得更高,Chrome 只会将其限制为 10 分钟,而 Safari 将其限制为仅5分钟)。
那么,关于问题中显示的特定请求,需要进行的具体更改和添加如下:
使用
Header always set
而不仅仅是Header set
。使用 mod_rewrite 只需发回带有这些标头的
200 OK
来处理OPTIONS
。请求
Access-Control-Request-Headers:authorization
,因此在 Apache 配置中,也在Access-Control-Allow-Headers
响应标头中添加Authorization
。Origin
是浏览器设置的"禁止"标头名称,Accept
是 CORS 安全列表的标头名称,因此无需将它们包含在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
/DELETE
/PATCH
请求,否则包括它们没有意义。