The 'Access-Control-Allow-Origin' header contains multiple values
Asked Answered
F

19

149

I'm using AngularJS $http on the client side to access an endpoint of a ASP.NET Web API application on the server side. As the client is hosted on a different domain as the server, I need CORS. It works for $http.post(url, data). But as soon as I authenticate the user and make a request via $http.get(url), I get the message

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 shows me that there are indeed two header entries in the get request after a successful options request. What and where am I doing something wrong?

Update

When I use jQuery $.get instead of $http.get, the same error message appears. So this seems no issue with AngularJS. But where is it wrong?

Fluvial answered 12/3, 2014 at 6:13 Comment(1)
Well, what does the header contain?Amateur
F
60

I added

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

as well as

app.UseCors(CorsOptions.AllowAll);

on the server. This results in two header entries. Just use the latter one and it works.

Fluvial answered 12/3, 2014 at 7:34 Comment(9)
It seems like you are reading Properties.Settings.Default.Cors from a settings file. Can you post an example? And what class is UseCors in?Liftoff
"Uncaught ReferenceError: EnableCorsAttribute is not defined" ??Bluebill
@Hoppe, please have a look at msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx. It explains, that the first parameter of the EnableCorsAttribute is the allowed origins. For example "*" to allow all.Fluvial
@Hoppe, UseCors is an extension method defined in the NuGet package Microsoft.Owin.Cors. S.f. katanaproject.codeplex.com/SourceControl/latest#src/….Fluvial
config.EnableCors(enableCorsAttribute) is usually called in WebApiConfig.cs - it's part of the Microsoft.AspNet.WebApi.Cors Nuget package, the use of which is described here: asp.net/web-api/overview/security/… app.UseCors(CorsOptions.AllowAll) is usually called in Startup.Auth.cs as part of configuring your identity provider (eg OAuth), and is part of the Microsoft.Owin.Cors Nuget package.Milli
where to put this?Abydos
FYI to add to Papa's answer: You can also set this in the web.config (which I did while troubleshooting something else). Alas, I had already added it to WebApiConfig.Register() and thus got the dual header entries. Same fix worked just use in one placeKarolynkaron
We needed CORS across all the calls to the site, so removed app.UseCors from the OWINStartup configuration and it solved the problem.Mentholated
For IAppBuilder app: CorsExtensions.UseCors(app, CorsOptions.AllowAll);Axiom
C
71

We ran into this problem because we had set up CORS according to best practice (e.g. http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api) AND ALSO had a custom header <add name="Access-Control-Allow-Origin" value="*"/> in web.config.

Remove the web.config entry, and all is well.

Contrary to @mww's answer, we still have EnableCors() in the WebApiConfig.cs AND an EnableCorsAttribute on the controller. When we took out one or the other, we ran into other issues.

Catron answered 12/1, 2015 at 22:16 Comment(7)
I removed this line <add name="Access-Control-Allow-Origin" value="*"/> and I had the following other two entries in the web.config file which I did not remove: <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />Sawdust
This is key, you must only enable CORS once, my issue was that I also had it enabled in my web.config as well as app.UseCors()...I removed the web.config entry and just used the app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); method instead.Combust
The line above saved my life! Make sure you do not enable CORS more than once, else this will happen and you will become very frustrated.Tub
removed the <add name="Access-Control-Allow-Headers" value="Content-Type" /> from web.config and fixed for meGermanous
Siva Karthikeyan - thank you. your way solved my issue.Ectoplasm
"This is key, you must only enable CORS once" <- THIS IS IT @MohammadSepahvand THANKS. Back to .NET and already caught surprised :D.Lambrecht
When I turn it on in the config file it tells me I have multiple headers. When I turn if off in the config file, it tells me I don't have any.Lal
F
60

I added

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

as well as

app.UseCors(CorsOptions.AllowAll);

on the server. This results in two header entries. Just use the latter one and it works.

Fluvial answered 12/3, 2014 at 7:34 Comment(9)
It seems like you are reading Properties.Settings.Default.Cors from a settings file. Can you post an example? And what class is UseCors in?Liftoff
"Uncaught ReferenceError: EnableCorsAttribute is not defined" ??Bluebill
@Hoppe, please have a look at msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx. It explains, that the first parameter of the EnableCorsAttribute is the allowed origins. For example "*" to allow all.Fluvial
@Hoppe, UseCors is an extension method defined in the NuGet package Microsoft.Owin.Cors. S.f. katanaproject.codeplex.com/SourceControl/latest#src/….Fluvial
config.EnableCors(enableCorsAttribute) is usually called in WebApiConfig.cs - it's part of the Microsoft.AspNet.WebApi.Cors Nuget package, the use of which is described here: asp.net/web-api/overview/security/… app.UseCors(CorsOptions.AllowAll) is usually called in Startup.Auth.cs as part of configuring your identity provider (eg OAuth), and is part of the Microsoft.Owin.Cors Nuget package.Milli
where to put this?Abydos
FYI to add to Papa's answer: You can also set this in the web.config (which I did while troubleshooting something else). Alas, I had already added it to WebApiConfig.Register() and thus got the dual header entries. Same fix worked just use in one placeKarolynkaron
We needed CORS across all the calls to the site, so removed app.UseCors from the OWINStartup configuration and it solved the problem.Mentholated
For IAppBuilder app: CorsExtensions.UseCors(app, CorsOptions.AllowAll);Axiom
A
50

I'm using Cors 5.1.0.0, after much headache, I discovered the issue to be duplicated Access-Control-Allow-Origin & Access-Control-Allow-Header headers from the server

Removed config.EnableCors() from the WebApiConfig.cs file and just set the [EnableCors("*","*","*")] attribute on the Controller class

Check this article for more detail.

Abundant answered 24/5, 2014 at 2:24 Comment(1)
this works for me, just make sure that you are not setting another like this <add name="Access-Control-Allow-Origin" value="*" /> in web.configAlgonkian
E
23

Add to Register WebApiConfig

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

Or 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>

BUT NOT BOTH

Evanston answered 8/3, 2019 at 15:28 Comment(5)
This was the key solution for me, don't do both.Bialystok
Thanks so much for the hint not to set both!Milford
Careful! Allowing all origins has security implications. It is best to set origin to only those you absolutely trust to avoid CSRF vulnerabilities.Pydna
Yes GuyPaddock for production environment I agreeEvanston
Exactly, this was the right solution: DON'T DO BOTH. I had WebApi and MVC; but had a conflict for using both configs.Boracic
P
11

Apache Server:

I spend the same, but it was because I had no quotation marks (") the asterisk in my file that provided access to the server, eg '.htaccess.':

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

You may also have a file '.htaccess' in a folder with another '.htaccess' out, eg

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

In your case instead of '*' asterisk would be the ip (http://127.0.0.1:9000) server that you give permission to serve data.

ASP.NET:

Check that there is no 'Access-Control-Allow-Origin' duplicate in your code.

Developer Tools:

With Chrome you can verify your request headers. Press the F12 key and go to the 'Network' tab, now run the AJAX request and will appear on the list, click and give all the information is there.

Access-Control-Allow-Origin: *

Postcard answered 22/3, 2014 at 0:41 Comment(2)
Sometimes its that easy... While trying to get those confounded web service to run on IIS/Chrome I played around with the Application_BeginRequest method, and forgot about it... duplication in my own code! Thanks for pointing me to the obvious! :)Tank
To get the CORS response headers, you'll also have to be simulating an actual cross-origin request, so it may not appear if you just look in the network tab on the running site. However, using something like DHC (chrome.google.com/webstore/detail/dhc-resthttp-api-client/…) to run your AJAX request will be technically be calling from a different domain, thus triggering CORS and allowing you to see the Access Control headers.Milli
V
11

I too had both OWIN as well as my WebAPI that both apparently needed CORS enabled separately which in turn created the 'Access-Control-Allow-Origin' header contains multiple values error.

I ended up removing ALL code that enabled CORS and then added the following to the system.webServer node of my Web.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>

Doing this satisfied CORS requirements for OWIN (allowing log in) and for WebAPI (allowing API calls), but it created a new problem: an OPTIONS method could not be found during preflight for my API calls. The fix for that was simple--I just needed to remove the following from the handlers node my Web.Config:

<remove name="OPTIONSVerbHandler" />

Hope this helps someone.

Valenevalenka answered 5/8, 2015 at 22:20 Comment(0)
M
9

Actually you cannot set multiple headers Access-Control-Allow-Origin (or at least it won't work in all browsers). Instead you can conditionally set an environment variable and then use it in Header directive:

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

So in this example the response header will be added only if a request header Origin matches RegExp: ^(https?://localhost|https://[a-z]+\.my\.base\.domain)$ (it basically means localhost over HTTP or HTTPS and *.my.base.domain over HTTPS).

Remember to enable setenvif module.

Docs:

BTW. The }e in %{ORIGIN_SUB_DOMAIN}e is not a typo. It's how you use environment variable in Header directive.

Meander answered 2/6, 2014 at 16:11 Comment(3)
Do you have a source for not setting multiple access control headers? I can't find anything that confirms this.Fondafondant
Very smart and clean solution. Worked for me.Budweis
@Fondafondant "Note: In practice the origin-list-or-null production is more constrained. Rather than allowing a space-separated list of origins, it is either a single origin or the string "null"." w3.org/TR/cors/#access-control-allow-origin-response-headerMeander
E
4

This happens when you have Cors option configured at multiple locations. In my case I had it at the controller level as well as in the Startup.Auth.cs/ConfigureAuth.

My understanding is if you want it application wide then just configure it under Startup.Auth.cs/ConfigureAuth like this...You will need reference to Microsoft.Owin.Cors

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

If you rather keep it at the controller level then you may just insert at the Controller level.

[EnableCors("http://localhost:24589", "*", "*")]
    public class ProductsController : ApiController
    {
        ProductRepository _prodRepo;
Endorsee answered 9/8, 2015 at 15:17 Comment(1)
In my case I had it set in both Web.Config and in MyAppApiConfig.cs. Removing it from the latter solved the problem for me.Hirokohiroshi
H
4

if you are in IIS you need to activate CORS in web.config, then you don't need to enable in App_Start/WebApiConfig.cs Register method

My solution was, commented the lines here:

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

and write in the web.config:

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

Hapless answered 26/10, 2017 at 2:0 Comment(0)
D
3

just had this problem with a nodejs server.

here is how i fixed it.
i run my node server through a nginx proxy and i set nginx and node to both allow cross domain requests and it didnt like that so i removed it from nginx and left it in node and all was well.

Daron answered 8/8, 2014 at 2:47 Comment(2)
Thank you for this answer! It solved a problem I couldn't solve for a long time with an nginx + Rack (Ruby) setup. Same issue, same solution: Turn off the header additions in nginx, and let the rack-cors gem handle the CORS stuff. Bam, fixed.Jabber
Same issue. Same solution. Thanks 🙌🏻Deutzia
N
3

So silly and simple:

This problem occurred for me when having two time Header always set Access-Control-Allow-Origin * inside my Apache config file. Once withing the VirtualHost tags and once inside a Limit tag:

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

Removing one entry resolved the issue.

I guess in the original post it would have been two times:

Header set Access-Control-Allow-Origin: "http://127.0.0.1:9000"
Nutpick answered 6/3, 2019 at 16:12 Comment(0)
P
2

This can also happen of course if you've actually set your Access-Control-Allow-Origin header to have multiple values - For example, a comma separated list of values, which is kind of supported in the RFC but isn't actually supported by most major browsers. Note that the RFC talks about how to allow more than one domain without using '*' as well.

For example, you can get that error in Chrome by using a header like so:

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

This was in Chrome Version 64.0.3282.186 (Official Build) (64-bit)

Note that if you're considering this because of a CDN, and you use Akamai, you may want to note that Akamai wont cache on the server if you use Vary:Origin, the way many suggest to solve this problem.

You'll probably have to change how your cache key is built, using a "Cache ID Modification" response behavior. More details on this issue in this related StackOverflow question

Pomiculture answered 13/3, 2018 at 17:38 Comment(4)
So basically, you can't right now because it is doubtful you will want every single domain on the internet to hit the url.Decarbonate
The Akamai link require to be logged in.Reider
yeah that appears to be an akamai requirement for those docs ;-(Pomiculture
Another way to get this error in Chrome is with a space-separated list of values: Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com. That would be the correct way, but browsers do not follow the standard here (source).Asynchronism
C
2

The 'Access-Control-Allow-Origin' header contains multiple values

when i received this error i spent tons of hours searching solution for this but nothing works, finally i found solution to this problem which is very simple. when ''Access-Control-Allow-Origin' header added more than one time to your response this error occur, check your apache.conf or httpd.conf (Apache server), server side script, and remove unwanted entry header from these files.

Closing answered 11/7, 2020 at 11:57 Comment(1)
Thank you! I had this error due to iisnode web.config file which had <customHeaders> xml tags adding to the allowed headers - so hard to find the root problem until seeing this post!Wixted
A
2

For only Spring Boot : This occurs because u might be using the

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

twice in the application or else, you might be using :

@CrossOrigin(origins = "*")

The browsers do not support it.Check here for more details on it

please specify the Url even in the security config :

@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;
}

Then Add this in the Http security configure :

.and().cors().configurationSource(corsConfigurationSource());
Alexalexa answered 25/5, 2022 at 13:21 Comment(0)
A
1

I have faced the same issue. The reason in my case was that I had the wrong NGINX configuration for reverse proxy (which I used for the Docker container with node.js app).

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

So for those who are using VMs and docker, there are more places where issues are possible to occur.

Argeliaargent answered 21/3, 2022 at 20:29 Comment(0)
D
0

I have faced the same issue and this is what I did to resolve it:

In the WebApi service, inside Global.asax I have written the following code:

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

Here this code only allows pre-flight and token request to add "Access-Control-Allow-Origin" in the response otherwise I am not adding it.

Here is my blog about the implementation: https://ibhowmick.wordpress.com/2018/09/21/cross-domain-token-based-authentication-with-web-api2-and-jquery-angular-5-angular-6/

Deyo answered 4/10, 2018 at 16:7 Comment(0)
A
0

for those who are using IIS with php, on IIS it server side update web.config file it root directory (wwwroot) and add this

<?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>

after that restart IIS server, type IISReset in RUN and enter

Adrianneadriano answered 15/10, 2018 at 6:56 Comment(0)
T
0

Here's another instance similar to the examples above that you may only have one config file define where CORS is: There were two web.config files on the IIS server on the path in different directories, and one of them was hidden in the virtual directory. To solve it I deleted the root level config file since the path was using the config file in the virtual directory. Have to choose one or the other.

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

Termless answered 7/2, 2019 at 21:41 Comment(0)
C
0

I had this issue because I add in the my webconfig project and also webconfig endpoint this config: <add name="Control-Allow-Origin" value="*"/>. When I remove <add name="Control-Allow-Origin" value="*"/> from webconfig endpoint the problem was solved.

Chino answered 31/3, 2022 at 3:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.