如何启用 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 虚拟主机配置如下所示:
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).
我不知道为什么 apache 不处理预检请求?
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
:您必须将其设置为包含您的请求发送的任何标头名称除了CORS-safelisted 标头名称 或所谓的 禁止的"标题名称(浏览器设置的标题名称,您无法在JavaScript);规范还允许使用 *
通配符 作为它的价值——所以你可以尝试它,虽然有些浏览器可能还不支持它:Chrome 错误、Firefox 错误, Safari 错误.
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, though some browsers may not support 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: *
, some browsers may not support it yet.
Access-Control-Expose-Headers
:设置为包含 Expires
、Cache-Control 之外的任何响应头
、Content-Type
、Pragma
、Last-Modified
和 Content-Language
,你的前端代码需要阅读.很多人忘记设置它并最终对为什么他们无法读取特定响应标头的值感到困惑).再次规范允许使用*
通配符 在这里,但有些浏览器可能还不支持.
Access-Control-Expose-Headers
: set to include any response headers beyond Expires
, Cache-Control
, Content-Type
, Pragma
, Last-Modified
, and Content-Language
that your frontend code needs to read. 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 some browsers may not support it yet.
Access-Control-Max-Age
:Chrome 的上限为 600
(10 分钟)硬编码,所以有为它设置更高的值没有任何意义(如果您将其设置得更高,Chrome 只会将其限制为 10 分钟,而 Safari 将其限制为仅 5 分钟).
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 (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 200 OK
with those headers.
请求有 Access-Control-Request-Headers:authorization
所以在 Apache 配置中,在 Access-Control-Allow 中添加
也是响应头.Authorization
-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 no 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 no need for it in Access-Control-Allow-Headers
in the response (and never needed for GET
requests and otherwise only needed if the type is not 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 including them.
这篇关于如何启用 CORS 的 Apache Web 服务器(包括预检和自定义标头)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!