Tho*_*ley 985 .htaccess http xmlhttprequest cross-domain cors
有没有办法允许多个跨域使用Access-Control-Allow-Origin标头?
我知道了*,但它太开放了.我真的想只允许一些域名.
举个例子,像这样:
Access-Control-Allow-Origin: http://domain1.example, http://domain2.example
Run Code Online (Sandbox Code Playgroud)
我已经尝试过上面的代码,但它似乎不适用于Firefox.
是否可以指定多个域,或者我只坚持一个?
小智 821
听起来像推荐的方法是让您的服务器从客户端读取Origin头,将其与您想要允许的域列表进行比较,如果匹配,则将Origin头的值回送给客户端,如Access-Control-Allow-Origin响应中的标头.
有了.htaccess你可以做这样的:
# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.example|dev02.otherdomain.example)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header merge Vary Origin
</IfModule>
</FilesMatch>
Run Code Online (Sandbox Code Playgroud)
Nik*_*nov 209
我在PHP中使用的另一个解决方案:
$http_origin = $_SERVER['HTTP_ORIGIN'];
if ($http_origin == "http://www.domain1.com" || $http_origin == "http://www.domain2.com" || $http_origin == "http://www.domain3.com")
{
header("Access-Control-Allow-Origin: $http_origin");
}
Run Code Online (Sandbox Code Playgroud)
Jay*_*ave 108
这对我有用:
SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.example|domain2\.example)$" origin_is=$0
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
Run Code Online (Sandbox Code Playgroud)
放入时.htaccess,它肯定会起作用.
小智 88
我有与woff-fonts相同的问题,多个子域必须具有访问权限.为了允许子域名,我在httpd.conf中添加了这样的内容:
SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1
<FilesMatch "\.woff$">
Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
</FilesMatch>
Run Code Online (Sandbox Code Playgroud)
对于多个域,您只需更改正则表达式即可SetEnvIf.
mja*_*day 62
以下是如果它与您的域与Nginx匹配时如何回显Origin头,如果您想要为多个子域提供字体,这非常有用:
location /fonts {
# this will echo back the origin header
if ($http_origin ~ "example.org$") {
add_header "Access-Control-Allow-Origin" $http_origin;
}
}
Run Code Online (Sandbox Code Playgroud)
Rak*_*kib 26
这是我为AJAX请求的PHP应用程序所做的
$request_headers = apache_request_headers();
$http_origin = $request_headers['Origin'];
$allowed_http_origins = array(
"http://myDumbDomain.example" ,
"http://anotherDumbDomain.example" ,
"http://localhost" ,
);
if (in_array($http_origin, $allowed_http_origins)){
@header("Access-Control-Allow-Origin: " . $http_origin);
}
Run Code Online (Sandbox Code Playgroud)
如果我的服务器允许请求源,则将$http_origin其自身作为Access-Control-Allow-Origin标头的值返回,而不是返回*通配符.
eye*_*hUp 23
对于 ExpressJS 应用程序,您可以使用:
app.use((req, res, next) => {
const corsWhitelist = [
'https://domain1.example',
'https://domain2.example',
'https://domain3.example'
];
if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
}
next();
});
Run Code Online (Sandbox Code Playgroud)
小智 20
您应该注意一个缺点:只要您将文件外包到CDN(或任何其他不允许编写脚本的服务器)或者您的文件缓存在代理上,就会根据"Origin"更改响应请求标头将无法正常工作.
Geo*_*rge 19
对于多个域,在您的.htaccess:
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(domain1.example|domain2.example)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule>
Run Code Online (Sandbox Code Playgroud)
Adr*_*osa 17
对于Nginx用户,允许CORS用于多个域.我喜欢@ marshall的例子,尽管他的答案只匹配一个域名.要匹配域和子域列表,此正则表达式可以轻松使用字体:
location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
if ( $http_origin ~* (https?://(.+\.)?(domain1|domain2|domain3)\.(?:me|co|com)$) ) {
add_header "Access-Control-Allow-Origin" "$http_origin";
}
}
Run Code Online (Sandbox Code Playgroud)
这将只回显与给定的域列表匹配的"Access-Control-Allow-Origin"标头.
duv*_*uvo 13
这是基于yesthatguy的答案的Java Web应用程序解决方案.
我正在使用Jersey REST 1.x.
配置web.xml以了解Jersey REST和CORSResponseFilter
<!-- Jersey REST config -->
<servlet>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.your.package.CORSResponseFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.your.package</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
这是CORSResponseFilter的代码
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
public class CORSResponseFilter implements ContainerResponseFilter{
@Override
public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {
String[] allowDomain = {"http://localhost:9000","https://my.domain.example"};
Set<String> allowedOrigins = new HashSet<String>(Arrays.asList (allowDomain));
String originHeader = request.getHeaderValue("Origin");
if(allowedOrigins.contains(originHeader)) {
response.getHttpHeaders().add("Access-Control-Allow-Origin", originHeader);
response.getHttpHeaders().add("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization");
response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHttpHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
her*_*vnc 11
如上所述,Access-Control-Allow-Origin应该是唯一的,如果您在CDN(内容交付网络)后面,Vary则应设置为Origin.
我的Nginx配置的相关部分:
if ($http_origin ~* (https?://.*\.mydomain.example(:[0-9]+)?)) {
set $cors "true";
}
if ($cors = "true") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'X-Frame-Options' "ALLOW FROM $http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Vary' 'Origin';
}
Run Code Online (Sandbox Code Playgroud)
也许我错了,但据我所知,Access-Control-Allow-Origin有一个"origin-list"参数.
根据定义,origin-list是:
origin = "origin" ":" 1*WSP [ "null" / origin-list ]
origin-list = serialized-origin *( 1*WSP serialized-origin )
serialized-origin = scheme "://" host [ ":" port ]
; <scheme>, <host>, <port> productions from RFC3986
Run Code Online (Sandbox Code Playgroud)
从这一点来说,我认为不同的起源被承认,应该是空间分离.
我努力为运行HTTPS的域设置这个,所以我想我会分享解决方案.我在httpd.conf文件中使用了以下指令:
<FilesMatch "\.(ttf|otf|eot|woff)$">
SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</FilesMatch>
Run Code Online (Sandbox Code Playgroud)
更改example.com为您的域名.<VirtualHost x.x.x.x:xx>在httpd.conf文件中添加它.请注意,如果你VirtualHost有一个端口后缀(例如:80),那么这个指令将不适用于HTTPS,所以你还需要转到/ etc/apache2/sites-available/default-ssl并在该文件中添加相同的指令,在里面该<VirtualHost _default_:443>部分.
更新配置文件后,您需要在终端中运行以下命令:
a2enmod headers
sudo service apache2 reload
Run Code Online (Sandbox Code Playgroud)
如果您在字体方面遇到麻烦,请使用:
<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
<IfModule mod_headers>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
Run Code Online (Sandbox Code Playgroud)
PHP代码:
$httpOrigin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : null;
if (in_array($httpOrigin, [
'http://localhost:9000', // Co-worker dev-server
'http://127.0.0.1:9001', // My dev-server
])) header("Access-Control-Allow-Origin: ${httpOrigin}");
header('Access-Control-Allow-Credentials: true');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
737991 次 |
| 最近记录: |