“ Access-Control-Allow-Origin”标头包含多个值


104

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

“ Access-Control-Allow-Origin”标头包含多个值“ http://127.0.0.1:9000、http://127.0.0.1:9000”,但只允许一个。因此,不允许访问来源“ http://127.0.0.1:9000”。

Fiddler向我展示了在成功的选项请求之后,get请求中确实存在两个标头条目。我在哪里和哪里做错了什么?

更新资料

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


好吧,标题包含什么?
eckes

Answers:


53

我加了

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

以及

app.UseCors(CorsOptions.AllowAll);

在服务器上。这将导致两个头条目。只需使用后者,它就可以工作。


4
似乎您正在从设置文件中读取Properties.Settings.Default.Cors。你能举个例子吗?UseCors属于哪一类?
Hoppe 2014年

“未捕获的ReferenceError:未定义EnableCorsAttribute”
电路

@Hoppe,请查看msdn.microsoft.com/zh-cn/library/dn314597(v=vs.118).aspx。它解释说,EnableCorsAttribute的第一个参数是允许的来源。例如,“ *”允许全部。
爸爸马福隆2014年

1
@ Hoppe,UseCors是在NuGet包Microsoft.Owin.Cors中定义的扩展方法。SF katanaproject.codeplex.com/SourceControl/latest#src/...
爸爸马福隆2014年

7
config.EnableCors(enableCorsAttribute)通常被称为WebApiConfig.cs -它的一部分,它的使用在这里描述的Microsoft.AspNet.WebApi.Cors NuGet包的:asp.net/web-api/overview/security/... 应用.UseCors(CorsOptions.AllowAll)通常在Startup.Auth.cs中作为配置身份提供程序(例如OAuth)的一部分被调用,并且是Microsoft.Owin.Cors Nuget包的一部分。
亨利C

51

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

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

与@mww的答案相反,我们仍然EnableCors()在WebApiConfig.cs中EnableCorsAttribute并在控制器上有一个。当我们取出一个或另一个时,我们遇到了其他问题。


11
我删除了这行<add name =“ Access-Control-Allow-Origin” value =“ *” />,并且在web.config文件中还有以下两个未删除的条目:<add name =“ Access -Control-Allow-Headers“ value =”内容类型“ /> <添加名称=” Access-Control-Allow-Methods“ value =” GET,POST,PUT,DELETE,OPTIONS“ />
Siva Karthikeyan

2
这是关键,您只必须启用一次CORS,我的问题是我也在我的web.config和app.UseCors()中启用了它。我删除了web.config条目并仅使用了该应用程序。 (Microsoft.Owin.Cors.CorsOptions.AllowAll); 方法代替。
Mohammad Sepahvand '16

1
上面的那条线救了我一命!确保您不多次启用CORS,否则会发生这种情况,并且您会感到非常沮丧。
TGarrett

从web.config中删除了<add name =“ Access-Control-Allow-Headers” value =“ Content-Type” />并为我修复了
jbooker

1
“这是关键,您只能启用一次CORS。” <-这是@MohammadSepahvand的感谢。回到.NET并已经感到惊讶:D。
Tuan Jinn

42

我使用的是Cors 5.1.0.0,经过很多头痛之后,我发现该问题与服务器中的Access-Control-Allow-Origin和Access-Control-Allow-Header标头重复

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

查看本文以获取更多详细信息。


这对我
有用

12

添加到注册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>

但不是两者


2
这是我的关键解决方案,请不要两者都做。
robnick

8

实际上,您不能设置多个标题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上的localhost以及HTTPS上的* .my.base.domain)。

记住要启用setenvif模块。

文件:

顺便说一句。在}e%{ORIGIN_SUB_DOMAIN}e是不是一个错字。这就是您在Header指令中使用环境变量的方式。


1
您是否有没有设置多个访问控制标头的来源?我找不到任何可以证实这一点的东西。
斯宾塞

非常聪明和干净的解决方案。为我工作。
Alex Kalmikov 2015年

@Spencer“注意:实际上,origin-list-or-null的产生更受限制。与其允许使用空格分隔的起源列表,不如说是单个起源或字符串” null“。” w3.org/TR/cors/#access-control-allow-origin-response-header
Nux

8

我也同时拥有OWIN和我的WebAPI,两者显然都需要分别启用CORS,这反过来又导致了'Access-Control-Allow-Origin' header contains multiple values错误。

我最终删除了所有启用CORS的代码,然后将以下代码添加到system.webServerWeb.Config 的节点中:

<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要求,但是这产生了一个新问题:OPTIONS在预检过程中找不到我的API调用的方法。修复很简单-我只需要从handlersWeb.Config节点中删除以下内容:

<remove name="OPTIONSVerbHandler" />

希望这对某人有帮助。


7

Apache服务器:

我花了相同的钱,但是那是因为我的文件中没有带星号的引号(“)来提供对服务器的访问,例如'.htaccess':

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

您可能还会在文件夹中有一个文件“ .htaccess”,而另一个文件是“ .htaccess”,例如

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

在您的情况下http://127.0.0.1:9000,您有权提供数据的ip()服务器而不是星号* 。

ASP.NET:

检查您的代码中是否没有“ Access-Control-Allow-Origin”重复项。

开发者工具:

使用Chrome,您可以验证请求标头。按F12键并转到“网络”选项卡,现在运行AJAX请求并将出现在列表中,单击并在其中提供所有信息。

访问控制允许来源:*


有时很容易...在尝试使那些混杂的Web服务在IIS / Chrome上运行时,我玩了Application_BeginRequest方法,却忘了它...在我自己的代码中重复!感谢您为我指出明显的内容!:)
Juergen Riemer 2014年

2
要获得CORS响应标头,您还必须模拟一个实际的跨域请求,因此,如果您仅查看运行站点上的“网络”标签,该请求可能不会出现。但是,使用DHC之类的东西(chrome.google.com/webstore/detail/dhc-resthttp-api-client/…)运行AJAX请求,从技术上讲会从其他域调用,从而触发CORS并允许您查看访问控制标头。
Henry C

4

当您在多个位置配置了Cors选项时,就会发生这种情况。就我而言,我在控制器级别以及Startup.Auth.cs / ConfigureAuth中都拥有它。

我的理解是,如果要在整个应用程序中使用它,则可以像这样在Startup.Auth.cs / ConfigureAuth下对其进行配置...您将需要引用Microsoft.Owin.Cors

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

如果您宁愿将其保留在控制器级别,则可以只在控制器级别插入。

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

就我而言,我在Web.Config和MyAppApiConfig.cs中都设置了它。从后者中删除它为我解决了问题。
Jim B

4

如果您在IIS中,则需要在web.config中激活CORS,则不需要在App_Start / WebApiConfig.cs中启用Register方法

我的解决方案是,在这里评论行:

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

并在web.config中编写:

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


2

如果您实际上已将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是许多人建议解决此问题的方法。

您可能必须使用“缓存ID修改”响应行为来更改缓存键的构建方式。有关此StackOverflow问题的更多详细信息


因此,基本上,您现在不能,因为您是否希望Internet上的每个域都可以到达该URL值得怀疑。
scottheckel

Akamai链接需要登录。
Jean-FrançoisSavard

是的,对于那些文档来说,这似乎是akaaka的要求;-(
Brad Parks

在Chrome中获取此错误的另一种方法是使用空格分隔的值列表:Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com。这是正确的做法,但浏览器不遵守此标准()。
tanius

2

如此愚蠢而简单:

Header always set Access-Control-Allow-Origin *我的Apache配置文件中有两次时,对我来说出现了这个问题。一旦withing的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"

1

刚刚有一个nodejs服务器的问题。

这是我固定的方式。
我通过a运行我的节点服务器,nginx proxy并同时设置了nginx和nginx,nodeallow cross domain requests不是那样,所以我从nginx中删除了它,并将其留在节点中,一切都很好。


感谢您的回答!它解决了我用nginx + Rack(Ruby)设置无法解决的问题。同样的问题,相同的解决方案:关闭nginx中的标头添加,然后让rack-corsgem处理CORS内容。巴姆,固定
Pistos

0

我遇到了同样的问题,这就是我要解决的问题:

在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

在此,此代码仅允许飞行前和令牌请求在响应中添加“ Access-Control-Allow-Origin”,否则我不会添加它。

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


0

对于那些使用IIS和php的用户,在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并输入


0

这是与上面的示例类似的另一个实例,您可能只有一个配置文件定义了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


0

“ Access-Control-Allow-Origin”标头包含多个值

当我收到此错误时,我花了数小时来寻找解决方案,但没有任何效果,最后我找到了解决此问题的方法,这很简单。当“ Access-Control-Allow-Origin”标头多次添加到您的响应时,发生此错误,请检查apache.conf或httpd.conf(Apache服务器),服务器端脚本,并从这些文件中删除不需要的条目标头。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.