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

Я использую 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. Но где это не так?

19 ответов

Решение

Я добавил

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

так же как

app.UseCors(CorsOptions.AllowAll);

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

Мы столкнулись с этой проблемой, потому что настроили 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 на контроллере. Когда мы убрали один или другой, мы столкнулись с другими проблемами.

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

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

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

Добавить в Реестр 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>

НО НЕ ОБА

У меня тоже был как 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 узел мой Web.Config:

<remove name="OPTIONSVerbHandler" />

Надеюсь, это кому-нибудь поможет.

Apache Server:

Я потратил то же самое, но это было потому, что у меня не было кавычек ("), звездочка в моем файле, которая обеспечивала доступ к серверу, например,".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:

Убедитесь, что в вашем коде нет дубликатов Access-Control-Allow-Origin.

Инструменты разработчика:

С Chrome вы можете проверить заголовки вашего запроса. Нажмите клавишу F12 и перейдите на вкладку "Сеть", теперь запустите запрос AJAX и появится в списке, нажмите и передайте всю имеющуюся информацию.

Access-Control-Allow-Origin

На самом деле вы не можете установить несколько заголовков 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 модуль.

Docs:

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

Это происходит, когда у вас есть опция 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;

Если вы находитесь в IIS, вам нужно активировать CORS в web.config, тогда вам не нужно включать метод 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>

Только что была эта проблема с сервером nodejs.

вот как я это исправил.
я запускаю свой сервер узлов через nginx proxy и я установил nginx и node как для allow cross domain requests и это не понравилось, поэтому я удалил его из nginx и оставил в узле, и все было хорошо.

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

Эта проблема возникла для меня, когда два раза 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"

Только для 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());

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

когда я получил эту ошибку, я потратил массу часов на поиск решения для нее, но ничего не работает, наконец, я нашел решение этой проблемы, которое очень просто. когда заголовок ''Access-Control-Allow-Origin'добавлялся к вашему ответу более одного раза, эта ошибка возникает, проверьте свой apache.conf или httpd.conf (сервер Apache), сценарий на стороне сервера и удалите ненужный заголовок записи из этих файлов.

Это также может произойти, если вы действительно установили 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 Modification". Подробнее об этой проблеме в этом связанном вопросе Stackru

Я столкнулся с той же проблемой. Причина в моем случае заключалась в том, что у меня была неправильная конфигурация NGINX для обратного прокси-сервера (который я использовал для контейнера Docker с приложением node.js).

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

Так что для тех, кто использует виртуальные машины и докер, есть больше мест, где могут возникнуть проблемы.

Для тех, кто использует 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 и введите

Я столкнулся с той же проблемой, и вот что я сделал, чтобы решить ее:

В сервисе 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/

У меня была эта проблема, потому что я добавляю в свой проект webconfig, а также в конечную точку webconfig эту конфигурацию: . Когда я удаляю <add name="Control-Allow-Origin" value="*"/>из конечной точки webconfig проблема была решена.

Вот еще один пример, аналогичный приведенным выше примерам: у вас может быть только один файл конфигурации, определяющий, где находится 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

Другие вопросы по тегам