飞行请求未由apache(CORS)处理

时间:2017-03-02 14:34:23

标签: apache http cors ip preflight

一般:

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没有处理预检请求?

1 个答案:

答案 0 :(得分:10)

您需要更改/添加的两件事是:

  • 使用Header always set代替Header set
  • 使用mod_rewrite处理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]

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-safelisted header names或所谓的{{ 3}}(由您无法在JavaScript中设置的浏览器设置的标题名称); “forbidden” header names作为其价值 - 所以你有一天可以尝试,但是还没有浏览器支持它: the spec alternatively allows the * wildcardChrome bugFirefox bug

  • Access-Control-Allow-Methods Safari bug - 但与Access-Control-Allow-Headers: *一样,没有任何浏览器支持它

  • Access-Control-Expose-Headers :您必须设置包含客户端代码需要阅读的所有响应标头Cache-ControlContent-Language,{{1} },Content-TypeExpiresLast-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-HeadersGETapplication/x-www-form-urlencoded

  • 之外的其他信息
  • 对于text/plain,您的请求似乎只是multipart/form-data,因此除非您打算同时Access-Control-Allow-Methods / GET / POST / PUT请求,明确包含它们没有意义