如何启用CORS的Apache web服务器(包括飞行前和自定义头)?

如何启用CORS的Apache web服务器(包括飞行前和自定义头)?,apache,http,cors,ip,preflight,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,

概述:

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>

标题集访问控制允许原点“http://127.0.0.1:3000"
标题集访问控制允许原点“http://127.0.0.1"
标题集访问控制最大年龄“300”
标题集访问控制允许凭据“true”
标题集访问控制允许标题“来源、X请求、内容类型、接受”
标题集访问控制允许方法“POST、GET、PUT、DELETE、PATCH、OPTIONS”
飞行前请求跳过apache配置并直接命中我的webapp,这将执行重定向(因此是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]
详细解释见

关于为各种
访问控制-
响应头设置哪些值的一些一般说明:

  • 访问控制允许标头
    :您必须将其设置为包含请求发送的任何标头名称,但     或所谓的(浏览器设置的标题名称,您无法在JavaScript中设置);作为它的价值,您可以在某一天尝试它,但还没有浏览器支持它:

  • 访问控制允许方法
    :-但是,与
    访问控制允许标题一样:
    ,还没有浏览器支持它

  • 访问控制公开标题
    :必须设置为包含客户端代码需要读取的超出
    缓存控制
    内容语言
    内容类型
    过期
    上次修改
    Pragma
    ——默认情况下公开的所有响应标题(很多人忘了设置这个,结果弄不明白为什么他们不能读取特定响应头的值);这里也是,但还没有浏览器支持它

  • 访问控制最大年龄
    :Chrome的上限为
    600
    (10分钟),因此没有必要为其设置更高的值(Firefox可能会尊重它,但如果您将其设置得更高,Chrome只会将其限制为10分钟,Safari将其限制为仅5分钟)


因此,关于问题中显示的特定请求,需要进行的具体更改和补充如下:

  • 使用
    标题始终设置
    ,而不仅仅是
    标题设置

  • 用于处理
    选项
    ,只需返回带有这些标题的
    200 OK

  • 请求具有
    访问控制请求头:授权
    ,因此在Apache配置中,在
    访问控制允许头
    响应头中添加
    授权

  • Origin
    是由浏览器设置的“禁止”标题名,
    Accept
    是CORS安全列表标题名,因此您不需要将它们包含在
    Access Control Allow Headers

  • 请求不发送
    内容类型
    ,因此响应中的
    访问控制允许标头
    中不需要它(并且
    获取
    请求从不需要它,除非类型不是
    应用程序/x-www-form-urlcoded
    文本/普通
    多部分/表单数据

  • 对于
    访问控制允许方法
    ,请求似乎只是一个
    获取
    ,因此,除非计划也发出
    发布
    /
    放置
    /
    删除
    /
    补丁
    请求,否则明确包含它们没有意义


谢谢!这是许多对我有用的帖子中的第一篇。让
标题始终设置访问控制允许来源“*”
似乎击败了CORS的作用。@ChrisStryczynski在上看到了答案。我知道有一些指南/消息来源断言或暗示CORS的作用是阻止其他网站访问您的内容。但实际上这根本不是CORS的作用-相反,CORS的作用是防止特权升级攻击。例如,请参阅上的答案。如果您的站点不使用/需要凭据进行访问,则不会有权限提升攻击来防止-
访问控制允许源代码:
可以安全使用。@ChrisStryczynski CORS实际上并不是用来阻止从其他站点对您的内容的所有访问,事实上,CORS i这根本不是阻止从其他网站访问您的内容的有效方法,因为您的内容仍然可以从服务器端的后端代码访问。因此,对于任何真正想阻止访问的人来说,设置某种身份验证机制是正确的方法,因为这也会阻止从服务器端访问后端代码。问题或答案都没有说明这个通配符,所以理想情况下应该提到这个警告。