“访问控制-允许-起源”头包含多个值

我在客户端使用 AngularJS $http 来访问服务器端 ASP.NET Web API 应用程序的端点。由于客户端作为服务器托管在不同的域上,因此我需要 CORS。它适用于 $http.post (url,data)。但是一旦我验证了用户并通过 $http.get (url)发出请求,就会得到消息

The 'Access-Control-Allow-Origin' header contains multiple values 'http://127.0.0.1:9000, http://127.0.0.1:9000', but only one is allowed. Origin 'http://127.0.0.1:9000' is therefore not allowed access.

Fiddler 告诉我,在成功的选项请求之后,get 请求中确实有两个头条目。我哪里做错了什么?

更新

当我使用 jQuery $。Get 而不是 $http.get,出现相同的错误消息。因此,这似乎没有问题 AngularJS。但是哪里出错了呢?

353449 次浏览

我加了一句

config.EnableCors(new EnableCorsAttribute(Properties.Settings.Default.Cors, "", ""))

还有

app.UseCors(CorsOptions.AllowAll);

在服务器上。这导致两个头条目。只要使用后一个和它的工作。

Apache 服务器:

我花了相同的,但这是因为我没有引号(“)星号在我的文件,提供访问服务器,例如’。Htaccess.':

Header add Access-Control-Allow-Origin: *
Header add Access-Control-Allow-Origin "*"

你也可能在文件夹中有一个文件“ . htaccess”,另一个文件夹中有一个文件“ . htaccess”,例如

/
- .htaccess
- public_html / .htaccess (problem here)

在您的示例中,星号而不是“ *”将是您授予服务数据权限的 ip (http://127.0.0.1:9000)服务器。

ASP.NET:

检查您的代码中没有“访问控制-允许-起源”副本。

开发工具:

使用 Chrome 你可以验证你的请求头。按下 F12键,进入“网络”选项卡,现在运行 AJAX 请求,将出现在列表中,点击并给出所有信息。

Access-Control-Allow-Origin: *

我正在使用 Cors 5.1.0.0,在经历了许多头痛之后,我发现这个问题被复制了 访问控制-允许-起源和访问控制-允许-头从服务器

从 WebApiConfig.cs 文件中删除了 config.EnableCors(),只在 Controller 类上设置了 [EnableCors("*","*","*")]属性

查看 这篇文章了解更多细节。

实际上,您不能设置多个头 Access-Control-Allow-Origin(或者至少它不能在所有浏览器中工作)。相反,你可以有条件地设置一个环境变量,然后在 Header指令中使用它:

SetEnvIf Origin "^(https?://localhost|https://[a-z]+\.my\.base\.domain)$" ORIGIN_SUB_DOMAIN=$1
Header set Access-Control-Allow-Origin: "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN

因此,在本例中,只有当请求头 Origin与 RegExp: ^(https?://localhost|https://[a-z]+\.my\.base\.domain)$匹配时,才会添加响应头(它基本上意味着通过 HTTP 或 HTTPS 和 * 的本地主机)。通过 HTTPS 访问 my.base.domain)。

记住启用 setenvif模块。

文件:

顺便说一下,%{ORIGIN_SUB_DOMAIN}e中的 }e不是打错了,而是你在 Header指令中使用环境变量的方式。

有个 Nodejs 服务器出了点问题。

我是这么解决的。
我通过 nginx proxy运行我的节点服务器,我把 nginx 和 node都设置为 allow cross domain requests,它不喜欢这样,所以我把它从 nginx 中删除,留在 node 中,一切都很好。

我们遇到这个问题是因为我们根据最佳实践(例如 http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api)设置了 CORS,并且在 web.config 中有一个自定义头 <add name="Access-Control-Allow-Origin" value="*"/>

删除 web.config 条目,一切正常。

与@mww 的回答相反,WebApiConfig.cs 中仍然有 EnableCors(),控制器中仍然有 EnableCorsAttribute。当我们除掉其中一个的时候,我们遇到了其他的问题。

我也有两个 OWIN 以及我的 WebAPI,两者显然都需要分别启用 CORS,这反过来又产生了 'Access-Control-Allow-Origin' header contains multiple values错误。

我最终删除了启用 CORS 的所有代码,然后将以下代码添加到我的 Web 的 system.webServer节点。配置:

<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="https://stethio.azurewebsites.net" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" />
</customHeaders>
</httpProtocol>

这样做满足了 OWIN (允许登录)和 WebAPI (允许 API 调用)的 CORS 需求,但是它产生了一个新问题: 在 API 调用的飞行前找不到 OPTIONS方法。这个问题的解决方案很简单——我只需要从我的 Web 的 handlers节点中删除以下内容。配置:

<remove name="OPTIONSVerbHandler" />

希望这对谁有帮助。

当您在多个位置配置了 Cors 选项时,就会发生这种情况。在我的案例中,我在控制器级别和启动阶段都有它。Auth.cs/configureauth.

我的理解是,如果你想它的应用广泛,然后只是配置它启动。像这样的 auth.cs/configureauth ... 你需要参考微软。欧文。科尔斯

public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);

如果您希望将它保持在控制器级别,那么可以只在控制器级别插入。

[EnableCors("http://localhost:24589", "*", "*")]
public class ProductsController : ApiController
{
ProductRepository _prodRepo;

如果您在 IIS 中,您需要激活 web.config 中的 CORS,那么您不需要在 App _ Start/WebApiConfig.cs Register 方法中启用 CORS

我的解决办法是,这里写道:

// Enable CORS
//EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
//config.EnableCors(cors);

然后在 web.config 中输入:

<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>

当然,如果您实际上已经将 Access-Control-Allow-Origin头部设置为具有多个值,也会发生这种情况——例如,以逗号分隔的值列表,这是 在 RFC 中支持的那种,但实际上不受大多数主要浏览器的支持。请注意,RFC 讨论了如何允许多个域也不使用’*’。

例如,你可以在 Chrome 中通过使用如下标题得到这个错误:

Access-Control-Allow-Origin: http://test.mysite.com, http://test2.mysite.com

这是在 Chrome Version 64.0.3282.186 (Official Build) (64-bit)

注意,如果您因为 CDN 而考虑这个问题,并且您使用 Akamai,那么您可能希望注意到 Akamai 不会缓存在服务器上,如果您使用 Vary:Origin,许多人建议用这种方法来解决这个问题。

您可能必须使用“ Cache ID 修改”响应行为更改缓存键的构建方式

我也面临过同样的问题,为了解决这个问题,我采取了以下措施:

在 WebApi 服务中,在 Global.asax 中,我编写了以下代码:

Sub Application_BeginRequest()
Dim currentRequest = HttpContext.Current.Request
Dim currentResponse = HttpContext.Current.Response


Dim currentOriginValue As String = String.Empty
Dim currentHostValue As String = String.Empty


Dim currentRequestOrigin = currentRequest.Headers("Origin")
Dim currentRequestHost = currentRequest.Headers("Host")


Dim currentRequestHeaders = currentRequest.Headers("Access-Control-Request-Headers")
Dim currentRequestMethod = currentRequest.Headers("Access-Control-Request-Method")


If currentRequestOrigin IsNot Nothing Then
currentOriginValue = currentRequestOrigin
End If


If currentRequest.Path.ToLower().IndexOf("token") > -1 Or Request.HttpMethod = "OPTIONS" Then
currentResponse.Headers.Remove("Access-Control-Allow-Origin")
currentResponse.AppendHeader("Access-Control-Allow-Origin", "*")
End If


For Each key In Request.Headers.AllKeys
If key = "Origin" AndAlso Request.HttpMethod = "OPTIONS" Then
currentResponse.AppendHeader("Access-Control-Allow-Credentials", "true")
currentResponse.AppendHeader("Access-Control-Allow-Methods", currentRequestMethod)
currentResponse.AppendHeader("Access-Control-Allow-Headers", If(currentRequestHeaders, "GET,POST,PUT,DELETE,OPTIONS"))
currentResponse.StatusCode = 200
currentResponse.End()
End If
Next


End Sub

这里的代码只允许飞行前和令牌请求在响应中添加“访问控制-允许-起源”,否则我不会添加它。

这是我关于实现的博客: https://ibhowmick.wordpress.com/2018/09/21/cross-domain-token-based-authentication-with-web-api2-and-jquery-angular-5-angular-6/

对于那些在 php 中使用 IIS 的用户, 在 IIS 它服务器端更新 web.config 文件它的根目录(wwwroot)并添加这个

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<directoryBrowse enabled="true" />
<httpProtocol>
<customHeaders>
<add name="Control-Allow-Origin" value="*"/>
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

在重启 IIS 服务器之后, 在 RUN 中键入 IISReset 并输入

下面是另一个与上面的例子类似的实例,您可能只有一个配置文件来定义 CORS 的位置: 在 IIS 服务器上的不同目录中有两个 web.config 文件,其中一个隐藏在虚拟目录中。 为了解决这个问题,我删除了根级别的配置文件,因为路径使用了虚拟目录中的配置文件。 必须选择其中一个。

URL called:  'https://example.com/foo/bar'
^              ^
CORS config file in root      virtual directory with another CORS config file
deleted this config             other sites using this


如此愚蠢和简单:

这个问题发生在我的 Apache 配置文件中有两次 Header always set Access-Control-Allow-Origin *时。一次使用 VirtualHost标签,一次使用 Limit标签:

<VirtualHost localhost:80>
...
Header set Access-Control-Allow-Origin: *
...
<Limit OPTIONS>
...
Header set Access-Control-Allow-Origin: *
...
</Limit>
</VirtualHost>

删除一个条目解决了问题。

我猜在最初的帖子里,有两次:

Header set Access-Control-Allow-Origin: "http://127.0.0.1:9000"

添加到注册 WebApiConfig

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

或者 web.config

<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>

但不能两者兼顾

“访问控制-允许-起源”头包含多个值

当我收到这个错误,我花了吨小时搜索解决方案,但没有工作,最后我发现这个问题的解决方案,这是非常简单的。 如果“ Access-Control-allow-Origin”头在响应中多次添加了此错误,请检查 Apache.conf 或 httpd.conf (Apache 服务器)、服务器端脚本,并从这些文件中删除不需要的条目头。

我也遇到过同样的问题。在我的例子中,原因是我为反向代理(我用于 node.js 应用程序的 Docker 容器)配置了错误的 NGINX。

 add_header 'Access-Control-Allow-Origin' '*'

因此,对于那些正在使用 VM 和 docker 的人来说,有更多可能发生问题的地方。

我有这个问题,因为我添加了我的 Webconfig 项目Webconfig 端点这个配置: <add name="Control-Allow-Origin" value="*"/>. 当我从 webconfig 端点删除 <add name="Control-Allow-Origin" value="*"/>时,问题就解决了。

只适用于 Spring Boot: 之所以会发生这种情况,是因为您可能正在使用

@CrossOrigin(origins = "http://localhost:4200")

在应用程序中使用两次,否则,您可能会使用:

@CrossOrigin(origins = "*")

浏览器不支持它

请在安全配置中指定 Url:

@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE"));
configuration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}

然后在 Http 安全配置中添加以下内容:

.and().cors().configurationSource(corsConfigurationSource());