我正在尝试为所有子域,端口和协议启用CORS。
例如,我希望能够从http://sub.mywebsite.example:8080/到https://www.mywebsite.example/*运行XHR请求
通常情况下,我想启用来自源匹配的请求(并且仅限于):
/ / * .mywebsite.example: * / *
我正在尝试为所有子域,端口和协议启用CORS。
例如,我希望能够从http://sub.mywebsite.example:8080/到https://www.mywebsite.example/*运行XHR请求
通常情况下,我想启用来自源匹配的请求(并且仅限于):
/ / * .mywebsite.example: * / *
当前回答
当在.htaccess中设置Access-Control-Allow-Origin时,只有以下几种有效:
SetEnvIf Origin "http(s)?://(.+\.)?domain\.example(:\d{1,5})?$" CRS=$0
Header always set Access-Control-Allow-Origin "%{CRS}e" env=CRS
我尝试了其他几个建议的关键字头追加,头集,没有工作建议在Stack Overflow上的许多答案,虽然我不知道这些关键字是否过时或对nginx无效。
以下是我的完整解决方案:
SetEnvIf Origin "http(s)?://(.+\.)?domain\.example(:\d{1,5})?$" CRS=$0
Header always set Access-Control-Allow-Origin "%{CRS}e" env=CRS
Header merge Vary "Origin"
Header always set Access-Control-Allow-Methods "GET, POST"
Header always set Access-Control-Allow-Headers: *
# Cached for a day
Header always set Access-Control-Max-Age: 86400
RewriteEngine On
# Respond with 200OK for OPTIONS
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
其他回答
我不得不稍微修改Lars的回答,因为正则表达式中出现了一个孤立的\,只比较实际的主机(不注意协议或端口),我想在我的生产域之外支持localhost域。因此,我将$allowed参数更改为一个数组。
function getCORSHeaderOrigin($allowed, $input)
{
if ($allowed == '*') {
return '*';
}
if (!is_array($allowed)) {
$allowed = array($allowed);
}
foreach ($allowed as &$value) {
$value = preg_quote($value, '/');
if (($wildcardPos = strpos($value, '\*')) !== false) {
$value = str_replace('\*', '(.*)', $value);
}
}
$regexp = '/^(' . implode('|', $allowed) . ')$/';
$inputHost = parse_url($input, PHP_URL_HOST);
if ($inputHost === null || !preg_match($regexp, $inputHost, $matches)) {
return 'none';
}
return $input;
}
用法如下:
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: " . getCORSHeaderOrigin(array("*.myproduction.com", "localhost"), $_SERVER['HTTP_ORIGIN']));
}
我在回答这个问题,因为公认的答案做不到跟随
正则表达式分组会影响性能,但这是不必要的。 不能匹配主域,只适用于子域。
例如:它不会为http://mywebsite.example发送CORS头,而为http://somedomain.mywebsite.example/工作
SetEnvIf Origin "http(s)?://(.+\.)?mywebsite\.com(:\d{1,5})?$" CORS=$0
Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS
Header merge Vary "Origin"
要启用你的网站,你只是把你的网站在mywebsite的地方。在上面的Apache配置的例子。
允许多个站点:
SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.example)(:\d{1,5})?$" CORS=$0
部署后验证:
下面的curl响应在更改后应该具有“Access-Control-Allow-Origin”标头。
curl -X GET -H "Origin: http://site1.example" --verbose http://site2.example/query
CORS规范是全有或全无。只支持*、null或精确的协议+域+端口:http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
您的服务器将需要使用正则表达式验证原点标头,然后您可以在Access-Control-Allow-Origin响应标头中回显原点值。
在我的例子中使用的是angular
在我的HTTP拦截器,我设置
with Credentials: true.
在请求头中
对于Spring Boot,我发现这个RegexCorsConfiguration扩展了官方的CorsConfiguration: https://github.com/looorent/spring-security-jwt/blob/master/src/main/java/be/looorent/security/jwt/RegexCorsConfiguration.java