如何启用 CORS 启用 Apache Web 服务器(包括预检和自定义标头)?



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:设置为包含前端代码需要读取的除ExpiresCache-ControlContent-TypePragmaLast-ModifiedContent-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-urlencodedtext/plainmultipart/form-data时才需要)。

  • 对于Access-Control-Allow-Methods来说,请求似乎只是一个GET,所以除非计划也提出POST/PUT/DELETE/PATCH请求,否则包括它们没有意义。

最新更新