如何启用CORS的Apache Web服务器(包括预检和自定义标头)? [英] How to CORS-enable Apache web server (including preflight and custom headers)?
问题描述
常规:
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配置如下:
Apache virtualhost config looks as so:
<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).
The preflight request is skipping the apache config and hitting my webapp directly, which does a redirect (hence the 302 and the location: y).
我不知道为什么apap无法处理预检请求?
I don't know why the preflight request is not being handled by apache?
推荐答案
要完全CORS启用Apache Web服务器,您需要将其配置为如下所示:
To fully CORS-enable an Apache web server, you need to have it configured to look like this:
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]
在关于为各种Access-Control-
响应标头设置哪些值的一些常规说明:
Some general notes on what values to set for the various Access-Control-
response headers:
-
Access-Control-Allow-Headers
:您必须将其设置为包含请求发送的所有标头名称, 禁止"标头名称(浏览器设置的标头名称,您无法在JavaScript中设置); 该规范还允许使用*
通配符作为其值,因此您有一天可以尝试使用,但尚无浏览器支持: Chrome错误, Firefox错误,
Access-Control-Allow-Headers
: you must set it to include any header names your request sends except CORS-safelisted header names or so-called "forbidden" header names (names of headers set by the browser that you can’t set in your JavaScript); the spec alternatively allows the*
wildcard as its value—so you can try it someday, but no browser supports it yet: Chrome bug, Firefox bug, Safari bug
Access-Control-Allow-Methods
:该规范还允许使用*
通配符-但是,与Access-Control-Allow-Headers: *
一样,目前还没有浏览器支持
Access-Control-Allow-Methods
: the spec alternatively allows the *
wildcard—but again, as with Access-Control-Allow-Headers: *
, no browsers support it yet
Access-Control-Expose-Headers
:您必须设置为包括客户端代码需要读取的所有响应标头,而这些内容应超出Cache-Control
,Content-Language
,Content-Type
,Expires
,Pragma
-默认情况下是公开的(很多人忘记设置此设置,最终对为什么他们无法读取特定响应头的值感到困惑);再次规范在此处也允许使用*
通配符,但是尚无浏览器支持
Access-Control-Expose-Headers
: you must set to include any response headers your client code needs to read beyond Cache-Control
,Content-Language
,Content-Type
, Expires
, Last-Modified
and Pragma
—which are exposed by default (a lot of people forget to set this and end up baffled about why they can’t read the value of a particular response header); again the spec alternatively allows the *
wildcard here, but no browsers support it yet
Access-Control-Max-Age
:Chrome的上限为600
(10分钟)
Access-Control-Max-Age
: Chrome has an upper limit of 600
(10 minutes) hardcoded, so there’s no point in setting a higher value for it than that (Firefox may respect it, but Chrome will just throttle it down to 10 minutes if you set it higher, and Safari limits it to only 5 minutes)
因此,关于问题中显示的特定请求,需要进行以下特定更改和添加:
So then, about the particular request shown in the question, the specific changes and additions that would need to made are these:
-
使用
Header always set
而不是Header set
使用 mod_rewrite 来处理OPTIONS
通过只发送带有这些标头的200 OK
Use mod_rewrite to handle the OPTIONS
by just sending back a 200 OK
with those headers
该请求具有Access-Control-Request-Headers:authorization
,因此在Apache配置中,也将Authorization
添加到Access-Control-Allow-Headers
响应标头中.
The request has Access-Control-Request-Headers:authorization
so in the Apache config, add Authorization
in the Access-Control-Allow-Headers
response header too.
Origin
是浏览器设置的禁止"标头名称,而Accept
是CORS安全列出的标头名称,因此您无需将它们包括在Access-Control-Allow-Headers
Origin
is a "forbidden" header name set by the browser, and Accept
is a CORS-safelisted header name, so you don’t need to include them in Access-Control-Allow-Headers
请求不发送任何Content-Type
,因此在响应中的Access-Control-Allow-Headers
中不需要它(对于GET
请求则从不需要,否则仅当类型不是application/x-www-form-urlencoded
时才需要, text/plain
或multipart/form-data
)
The request sends no Content-Type
, so it isn’t needed in Access-Control-Allow-Headers
in the response (and never needed for GET
requests and otherwise only needed if the type is other than application/x-www-form-urlencoded
, text/plain
, or multipart/form-data
)
对于Access-Control-Allow-Methods
,该请求似乎只是一个GET
,因此,除非计划也提出了POST
/PUT
/DELETE
/PATCH
请求,否则没有明确要求包括他们
For Access-Control-Allow-Methods
, the request seems to just be a GET
, so unless the plan’s to also make POST
/PUT
/DELETE
/PATCH
requests, no point in explicitly including them
这篇关于如何启用CORS的Apache Web服务器(包括预检和自定义标头)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!