Nagłówek „Access-Control-Allow-Origin” zawiera wiele wartości

104

Używam AngularJS $ http po stronie klienta, aby uzyskać dostęp do punktu końcowego aplikacji ASP.NET Web API po stronie serwera. Ponieważ klient jest hostowany w innej domenie niż serwer, potrzebuję CORS. Działa dla $ http.post (url, dane). Ale jak tylko uwierzytelnię użytkownika i wyślę żądanie za pośrednictwem $ http.get (url), otrzymuję wiadomość

Nagłówek „Access-Control-Allow-Origin” zawiera wiele wartości „http://127.0.0.1:9000, http://127.0.0.1:9000”, ale dozwolona jest tylko jedna. Dlatego Origin „http://127.0.0.1:9000” nie ma dostępu.

Fiddler pokazuje mi, że rzeczywiście istnieją dwa wpisy nagłówka w żądaniu get po pomyślnym żądaniu opcji. Co i gdzie robię coś złego?

Aktualizacja

Kiedy używam jQuery $ .get zamiast $ http.get, pojawia się ten sam komunikat o błędzie. Więc wydaje się, że nie ma problemu z AngularJS. Ale gdzie jest źle?

Papa Mufflon
źródło
Co zawiera nagłówek?
eckes

Odpowiedzi:

53

dodałem

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

jak również

app.UseCors(CorsOptions.AllowAll);

na serwerze. Powoduje to dwa wpisy nagłówka. Po prostu użyj tego drugiego i działa.

Papa Mufflon
źródło
4
Wygląda na to, że czytasz Properties.Settings.Default.Cors z pliku ustawień. Czy możesz zamieścić przykład? A w jakiej klasie jest UseCors?
Hoppe
„Uncaught ReferenceError: EnableCorsAttribute nie jest zdefiniowane” ??
obwody elektryczne
@Hoppe, zajrzyj na msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx . Wyjaśnia, że ​​pierwszy parametr EnableCorsAttribute to dozwolone źródła. Na przykład „*”, aby zezwolić wszystkim.
Papa Mufflon
1
@Hoppe, UseCors to metoda rozszerzenia zdefiniowana w pakiecie NuGet Microsoft.Owin.Cors. Sf katanaproject.codeplex.com/SourceControl/latest#src/… .
Papa Mufflon,
7
config.EnableCors (enableCorsAttribute) jest zwykle wywoływany w WebApiConfig.cs - jest częścią pakietu Microsoft.AspNet.WebApi.Cors Nuget, którego użycie jest opisane tutaj: asp.net/web-api/overview/security/ ... app .UseCors (CorsOptions.AllowAll) jest zwykle wywoływana w Startup.Auth.cs w ramach konfigurowania dostawcy tożsamości (np. OAuth) i jest częścią pakietu Microsoft.Owin.Cors Nuget.
Henry C
51

Napotkaliśmy ten problem, ponieważ skonfigurowaliśmy CORS zgodnie z najlepszymi praktykami (np. Http://www.asp.net/web-api/overview/security/eniring-cross-origin-requests-in-web-api ) ORAZ RÓWNIEŻ miał niestandardowy nagłówek <add name="Access-Control-Allow-Origin" value="*"/>w web.config.

Usuń wpis web.config i wszystko jest w porządku.

Wbrew odpowiedzi @ mww nadal mamy EnableCors()w WebApiConfig.cs ORAZ EnableCorsAttributena kontrolerze. Kiedy wyjęliśmy jeden lub drugi, napotkaliśmy inne problemy.

Brandon Kuczenski
źródło
11
Usunąłem tę linię <add name = "Access-Control-Allow-Origin" value = "*" /> i miałem następujące dwa inne wpisy w pliku web.config, których nie usunąłem: <add name = "Access -Control-Allow-Headers "value =" Content-Type "/> <add name =" Access-Control-Allow-Methods "value =" GET, POST, PUT, DELETE, OPTIONS "/>
Siva Karthikeyan,
2
To jest klucz, musisz włączyć CORS tylko raz, moim problemem było to, że miałem go również włączony w moim web.config, a także w aplikacji.UseCors () ... Usunąłem wpis web.config i właśnie użyłem aplikacji. (Microsoft.Owin.Cors.CorsOptions.AllowAll); zamiast metody.
Mohammad Sepahvand,
1
Powyższa linia uratowała mi życie! Upewnij się, że nie włączasz CORS więcej niż jeden raz, w przeciwnym razie tak się stanie i będziesz bardzo sfrustrowany.
TGarrett
usunąłem <add name = "Access-Control-Allow-Headers" value = "Content-Type" /> z web.config i naprawiono dla mnie
jbooker,
1
„To jest klucz, musisz włączyć CORS tylko raz” <- TO JEST @MohammadSepahvand DZIĘKUJĘ. Wracając do .NET i już jestem zaskoczony: D.
Tuan Jinn
42

Używam Cors 5.1.0.0, po wielu bólach głowy odkryłem, że problem jest zduplikowany w nagłówkach Access-Control-Allow-Origin i Access-Control-Allow-Header z serwera

Usunięto config.EnableCors()z pliku WebApiConfig.cs i po prostu ustawiono [EnableCors("*","*","*")]atrybut w klasie Controller

Sprawdzić ten artykuł , aby uzyskać więcej szczegółów.

mww
źródło
to działa dla mnie, po prostu upewnij się, że nie ustawiasz innego podobnego do tego <add name = "Access-Control-Allow-Origin" value = "*" /> w web.config
Crismogram
12

Dodaj, aby zarejestrować WebApiConfig

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

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

ALE NIE OBA

tfa
źródło
2
To było dla mnie kluczowe rozwiązanie, nie rób obu.
robnick
8

W rzeczywistości nie możesz ustawić wielu nagłówków Access-Control-Allow-Origin(a przynajmniej nie będzie działać we wszystkich przeglądarkach). Zamiast tego możesz warunkowo ustawić zmienną środowiskową, a następnie użyć jej w Headerdyrektywie:

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

W tym przykładzie nagłówek odpowiedzi zostanie dodany tylko wtedy, gdy nagłówek żądania jest Originzgodny z RegExp: ^(https?://localhost|https://[a-z]+\.my\.base\.domain)$(zasadniczo oznacza to localhost przez HTTP lub HTTPS i * .my.base.domain przez HTTPS).

Pamiętaj, aby włączyć setenvifmoduł.

Dokumenty:

BTW. }eW %{ORIGIN_SUB_DOMAIN}enie jest literówka. Tak używasz zmiennej środowiskowej w Headerdyrektywie.

Nux
źródło
1
Czy masz źródło, z którego nie można ustawiać wielu nagłówków kontroli dostępu? Nie mogę znaleźć niczego, co to potwierdza.
Spencer,
Bardzo sprytne i czyste rozwiązanie. Pracował dla mnie.
Alex Kalmikov
@Spencer "Uwaga: w praktyce produkcja listy-lub-wartości-pochodzenia jest bardziej ograniczona. Zamiast zezwalać na listę źródeł oddzielonych spacjami, jest to albo pojedyncze źródło, albo ciąg znaków" null " ." w3.org/TR/cors/#access-control-allow-origin-response-header
Nux
8

Ja również miałem zarówno OWIN, jak i moje WebAPI, które najwyraźniej wymagały osobnego włączenia CORS, co z kolei spowodowało 'Access-Control-Allow-Origin' header contains multiple valuesbłąd.

Skończyło się na usunięciu CAŁEGO kodu, który włączał CORS, a następnie dodałem następujący element do system.webServerwęzła mojego 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>

Spowodowało to spełnienie wymagań CORS dla OWIN (zezwalające na logowanie) i dla WebAPI (zezwalające na wywołania API), ale stworzyło nowy problem: OPTIONSnie można było znaleźć metody podczas inspekcji wstępnej dla moich wywołań API. Rozwiązanie tego problemu było proste - wystarczyło usunąć następujące elementy z handlerswęzła my Web.Config:

<remove name="OPTIONSVerbHandler" />

Mam nadzieję, że to komuś pomoże.

Matt Cashatt
źródło
7

Serwer Apache:

Wydałem tyle samo, ale to dlatego, że nie miałem cudzysłowu (") gwiazdki w moim pliku, która zapewniała dostęp do serwera, np. '.Htaccess.':

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

Możesz również mieć plik „.htaccess” w folderze z innym plikiem „.htaccess”, np

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

W twoim przypadku zamiast gwiazdki „*” oznaczałby http://127.0.0.1:9000serwer ip ( ), któremu zezwalasz na udostępnianie danych.

ASP.NET:

Sprawdź, czy w Twoim kodzie nie ma duplikatu „Access-Control-Allow-Origin”.

Narzędzia deweloperskie:

W Chrome możesz zweryfikować nagłówki żądań. Naciśnij klawisz F12 i przejdź do zakładki 'Sieć', teraz uruchom żądanie AJAX i pojawi się na liście, kliknij i podaj wszystkie informacje tam.

Access-Control-Allow-Origin: *

Chofoteddy
źródło
Czasami jest to takie proste ... Próbując uruchomić te pomieszane usługi internetowe w IIS / Chrome, bawiłem się metodą Application_BeginRequest i zapomniałem o tym ... powielanie w moim własnym kodzie! Dzięki za wskazanie mi oczywistości! :)
Juergen Riemer
2
Aby uzyskać nagłówki odpowiedzi CORS, musisz również symulować rzeczywiste żądanie między źródłami, więc może się nie pojawić, jeśli spojrzysz tylko na kartę sieci w działającej witrynie. Jednak użycie czegoś takiego jak DHC ( chrome.google.com/webstore/detail/dhc-resthttp-api-client/ ) do uruchomienia żądania AJAX będzie technicznie wywoływać z innej domeny, uruchamiając w ten sposób CORS i umożliwiając wyświetlenie nagłówki kontroli dostępu.
Henry C
4

Dzieje się tak, gdy masz opcję Cors skonfigurowaną w wielu lokalizacjach. W moim przypadku miałem to na poziomie kontrolera, a także w Startup.Auth.cs / ConfigureAuth.

Rozumiem, że jeśli chcesz, aby aplikacja była szeroka, po prostu skonfiguruj ją w Startup.Auth.cs / ConfigureAuth w ten sposób ... Będziesz potrzebować odniesienia do Microsoft.Owin.Cors

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

Jeśli wolisz zachować go na poziomie kontrolera, możesz po prostu wstawić na poziomie kontrolera.

[EnableCors("http://localhost:24589", "*", "*")]
    public class ProductsController : ApiController
    {
        ProductRepository _prodRepo;
Nizar
źródło
W moim przypadku ustawiłem go zarówno w Web.Config, jak iw MyAppApiConfig.cs. Usunięcie go z tego ostatniego rozwiązało problem za mnie.
Jim B
4

jeśli jesteś w IIS, musisz aktywować CORS w web.config, to nie musisz włączać metody App_Start / WebApiConfig.cs Register

Moim rozwiązaniem było, skomentował linie tutaj:

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

i napisz w web.config:

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

freedeveloper
źródło
2

Może się to oczywiście zdarzyć, jeśli faktycznie ustawisz Access-Control-Allow-Originnagłówek tak, aby miał wiele wartości - na przykład lista wartości oddzielonych przecinkami, która jest w pewnym sensie obsługiwana w RFC, ale w rzeczywistości nie jest obsługiwana przez większość głównych przeglądarek. Zwróć uwagę, że dokument RFC mówi o tym, jak zezwolić na więcej niż jedną domenę bez używania „*”.

Na przykład możesz uzyskać ten błąd w Chrome, używając takiego nagłówka:

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

To było w Chrome Version 64.0.3282.186 (Official Build) (64-bit)

Zauważ, że jeśli rozważasz to ze względu na CDN i używasz Akamai, możesz zauważyć, że Akamai nie będzie buforował pamięci na serwerze, jeśli używasz Vary:Origin , sposób, w jaki wielu sugeruje rozwiązanie tego problemu.

Prawdopodobnie będziesz musiał zmienić sposób budowania klucza pamięci podręcznej, używając zachowania odpowiedzi „Modyfikacja identyfikatora pamięci podręcznej”. Więcej szczegółów na ten temat w tym pokrewnym pytaniu dotyczącym StackOverflow

Brad Parks
źródło
Zasadniczo nie możesz teraz, ponieważ wątpliwe jest, aby każda domena w Internecie trafiała do adresu URL.
scottheckel
Link Akamai wymaga zalogowania.
Jean-François Savard
tak, to wydaje się być wymogiem akamai dla tych dokumentów ;-(
Brad Parks
Innym sposobem, aby dostać ten błąd w Chrome jest z rozdzieloną spacjami listą wartości: Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com. To byłby właściwy sposób, ale przeglądarki nie przestrzegają tutaj standardu ( źródło ).
tanius
2

Tak głupie i proste:

Ten problem wystąpił podczas dwukrotnego przebywania Header always set Access-Control-Allow-Origin *w moim pliku konfiguracyjnym Apache. Raz z VirtualHosttagami i raz wewnątrz Limittagu:

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

Usunięcie jednego wpisu rozwiązało problem.

Myślę, że w oryginalnym poście byłoby to dwa razy:

Header set Access-Control-Allow-Origin: "http://127.0.0.1:9000"
Więdnąć
źródło
1

właśnie miałem ten problem z serwerem nodejs.

oto jak to naprawiłem.
Uruchomiłem serwer węzłów przez nginx proxya i ustawiłem nginx i nodeoba allow cross domain requestsi nie podobało mi się to, więc usunąłem go z nginx i zostawiłem w węźle i wszystko było dobrze.

James Harrington
źródło
Dziękuję za tę odpowiedź! Rozwiązało problem, którego nie mogłem rozwiązać przez długi czas z konfiguracją nginx + Rack (Ruby). Ten sam problem, to samo rozwiązanie: wyłącz dodawanie nagłówków w nginx i pozwól rack-corsklejnotowi obsługiwać elementy CORS. Bam, naprawione.
Pistos,
0

Napotkałem ten sam problem i oto, co zrobiłem, aby go rozwiązać:

W serwisie WebApi wewnątrz Global.asax napisałem następujący kod:

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

Tutaj ten kod zezwala tylko na żądanie przed lotem i tokenem, aby dodać „Access-Control-Allow-Origin” w odpowiedzi, w przeciwnym razie nie dodam go.

Oto mój blog dotyczący wdrożenia: https://ibhowmick.wordpress.com/2018/09/21/cross-domain-token-based-authentication-with-web-api2-and-jquery-angular-5-angular- 6 /

indranil bhowmick
źródło
0

dla tych, którzy używają IIS z php, na serwerze IIS it zaktualizuj plik web.config do katalogu głównego (wwwroot) i dodaj to

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

po tym zrestartuj serwer IIS, wpisz IISReset w RUN i wprowadź

user889030
źródło
0

Oto inne wystąpienie podobne do powyższych przykładów, że możesz mieć tylko jeden plik konfiguracyjny definiujący miejsce CORS: Na serwerze IIS znajdowały się dwa pliki web.config w ścieżce w różnych katalogach, a jeden z nich był ukryty w katalogu wirtualnym. Aby rozwiązać ten problem, usunąłem plik konfiguracyjny poziomu głównego, ponieważ ścieżka używała pliku konfiguracyjnego w katalogu wirtualnym. Musisz wybrać jedną lub drugą.

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

Cliff Coulter
źródło
0

Nagłówek „Access-Control-Allow-Origin” zawiera wiele wartości

kiedy otrzymałem ten błąd, spędziłem mnóstwo godzin na szukaniu rozwiązania tego problemu, ale nic nie działa, w końcu znalazłem rozwiązanie tego problemu, które jest bardzo proste. gdy nagłówek `` Access-Control-Allow-Origin '' został dodany więcej niż jeden raz do Twojej odpowiedzi, ten błąd występuje, sprawdź swój apache.conf lub httpd.conf (serwer Apache), skrypt po stronie serwera i usuń niechciany nagłówek wpisu z tych plików .

Jiten Mhatre
źródło