Заголовок Access-Control-Allow-Origin содержит несколько значений.

104

Я использую AngularJS $ http на стороне клиента для доступа к конечной точке приложения веб-API ASP.NET на стороне сервера. Поскольку клиент размещен в другом домене, чем сервер, мне нужен 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 показывает мне, что в запросе на получение действительно есть две записи заголовка после успешного запроса параметров. Что и где я делаю не так?

Обновить

Когда я использую jQuery $ .get вместо $ http.get, появляется то же сообщение об ошибке. Так что с AngularJS это не проблема. Но где это не так?

Папа Маффлон
источник
Ну что в шапке?
eckes

Ответы:

53

я добавил

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

так же как

app.UseCors(CorsOptions.AllowAll);

на сервере. Это приводит к двум записям заголовка. Просто используйте последний, и он работает.

Папа Маффлон
источник
4
Похоже, вы читаете Properties.Settings.Default.Cors из файла настроек. Можете опубликовать пример? А в каком классе находится UseCors?
Hoppe
«Неперехваченная ReferenceError: EnableCorsAttribute не определен» ??
схемотехника
@Hoppe, пожалуйста, посмотрите msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx . Он объясняет, что первый параметр EnableCorsAttribute - это разрешенные источники. Например, «*» разрешить все.
Папа Маффлон
1
@Hoppe, UseCors - это метод расширения, определенный в пакете NuGet Microsoft.Owin.Cors. Sf katanaproject.codeplex.com/SourceControl/latest#src/… .
Папа Маффлон,
7
config.EnableCors (enableCorsAttribute) обычно вызывается в WebApiConfig.cs - это часть пакета Nuget Microsoft.AspNet.WebApi.Cors, использование которого описано здесь: asp.net/web-api/overview/security/… app .UseCors (CorsOptions.AllowAll) обычно вызывается в Startup.Auth.cs как часть настройки вашего поставщика удостоверений (например, OAuth) и является частью пакета Nuget Microsoft.Owin.Cors.
Henry C
51

Мы столкнулись с этой проблемой, потому что мы настроили CORS в соответствии с передовой практикой (например, http://www.asp.net/web-api/overview/security/enpting-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 =" Content-Type "/> <add name =" Access-Control-Allow-Methods "value =" GET, POST, PUT, DELETE, OPTIONS "/>
Сива Картикеян
2
Это ключевой момент, вы должны включить CORS только один раз, моя проблема заключалась в том, что он также был включен в моем web.config, а также в app.UseCors () ... Я удалил запись web.config и просто использовал app.UseCors (Microsoft.Owin.Cors.CorsOptions.AllowAll); вместо этого.
Мохаммад Сепахванд
1
Строка выше спасла мне жизнь! Убедитесь, что вы не включаете CORS более одного раза, иначе это произойдет, и вы очень расстроитесь.
TGarrett
удалил значение <add name = "Access-Control-Allow-Headers" value = "Content-Type" /> из web.config и исправил для меня
jbooker
1
«Это ключ, вы должны включить CORS только один раз» <- ЭТО ЭТО @MohammadSepahvand СПАСИБО. Вернулся в .NET и уже застал удивлен: D.
Туан Джинн
42

Я использую Cors 5.1.0.0, после долгой головной боли я обнаружил, что проблема дублируется заголовками Access-Control-Allow-Origin и Access-Control-Allow-Header с сервера

Удалил config.EnableCors()из файла WebApiConfig.cs и просто установил [EnableCors("*","*","*")]атрибут в классе Controller

Прочтите эту статью для получения более подробной информации.

мвв
источник
это работает для меня, просто убедитесь, что вы не устанавливаете другое подобное значение <add name = "Access-Control-Allow-Origin" = "*" /> в web.config
Crismogram
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>

НО НЕ ОБОИХ

tfa
источник
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)$(это в основном означает localhost через HTTP или HTTPS и * .my.base.domain через HTTPS).

Не забудьте включить setenvifмодуль.

Документы:

Кстати. }eВ %{ORIGIN_SUB_DOMAIN}eэто не опечатка. Это то, как вы используете переменную среды в Headerдирективе.

Nux
источник
1
У вас есть источник, чтобы не устанавливать заголовки управления множественным доступом? Я не могу найти ничего, подтверждающего это.
Спенсер
Очень умное и чистое решение. Работал у меня.
Alex Kalmikov
@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.webServerузел моего 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>

Выполнение этого удовлетворило требования CORS для OWIN (разрешение входа в систему) и для WebAPI (разрешение вызовов API), но создало новую проблему: OPTIONSне удалось найти метод во время предварительной проверки для моих вызовов API. Исправить это было просто - мне просто нужно было удалить следующее из handlersузла my Web.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 и появится в списке, нажмите и укажите всю информацию, которая там есть.

Доступ-Контроль-Разрешить-Происхождение: *

Чофотедди
источник
Иногда это так просто ... Пытаясь запустить эти запутанные веб-службы в IIS / Chrome, я поигрался с методом Application_BeginRequest и забыл об этом ... дублирование в моем собственном коде! Спасибо, что указали мне на очевидное! :)
Юрген Ример
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, вам нужно активировать CORS в web.config, тогда вам не нужно включать метод регистрации App_Start / WebApiConfig.cs

Мое решение было прокомментировано здесь:

// 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 , как многие предлагают решить эту проблему.

Вероятно, вам придется изменить способ создания ключа кеша, используя поведение ответа «Изменение идентификатора кэша». Дополнительные сведения об этой проблеме см. В соответствующем вопросе StackOverflow.

Брэд Паркс
источник
По сути, вы не можете прямо сейчас, потому что сомнительно, чтобы каждый домен в Интернете попадал по URL-адресу.
scottheckel
Ссылка Akamai требует входа в систему.
Жан-Франсуа Савар
да, похоже, это требование акамая для этих документов ;-(
Брэд Паркс,
Другой способ получить эту ошибку в Chrome есть с разделенными пробелами списка значений: Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com. Это было бы правильным способом, но браузеры не следуют стандарту здесь ( источник ).
tanius
2

Так глупо и просто:

Эта проблема возникла у меня, когда у меня было два раза Header always set Access-Control-Allow-Origin *в моем файле конфигурации Apache. Один раз с 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 и nodeна оба, allow cross domain requestsи ему это не понравилось, поэтому я удалил его из nginx и оставил в узле, и все было хорошо.

Джеймс Харрингтон
источник
Спасибо за такой ответ! Он решил проблему, которую я долгое время не мог решить с помощью установки nginx + Rack (Ruby). Та же проблема, такое же решение: отключите добавление заголовков в nginx и позвольте rack-corsдрагоценному камню обрабатывать материал 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, введите IISReset в RUN и введите

user889030
источник
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), сценарий на стороне сервера и удалите ненужный заголовок записи из этих файлов .

Джитен Мхатре
источник