Подтвердить что ты не робот

Отсутствует токен 'access-control-allow-headers' в заголовке CORS 'Access-Control-Allow-Headers' из канала предпросмотра CORS

У меня есть два проекта VS: один из них выдает контроллеры MVC5, другой - клиент angular. Я хочу, чтобы клиент angular мог запросить контроллеры. Я прочитал множество потоков и попробовал следующее:

  • Я добавил это в веб-конфигурацию сервера:

    <system.webServer>
        <httpProtocol>
           <customHeaders>
                <clear />
                <add name="Access-Control-Allow-Origin" value="*" />
            </customHeaders>
        </httpProtocol>
    <system.webServer>
    
  • Я создал и использовал следующий фильтр для действия контроллера:

    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }
    
  • В клиенте angular я создал следующий перехватчик:

    app.factory("CORSInterceptor", [
        function()
        {
            return {
                request: function(config)
                {
                     config.headers["Access-Control-Allow-Origin"] = "*";
                     config.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
                     config.headers["Access-Control-Allow-Headers"] = "Content-Type";
                     config.headers["Access-Control-Request-Headers"] = "X-Requested-With, accept, content-type";
                     return config;
                }
         };
    }
    ]);
    
    app.config(["$httpProvider", function ($httpProvider) {
        $httpProvider.interceptors.push("CORSInterceptor");
    }]);
    

Согласно Firebug, это приводит к следующему запросу:

OPTIONS //Login/Connect HTTP/1.1
Host: localhost:49815
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:50739
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-origin,content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

И следующий ответ:

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-SourceFiles: =?UTF-8?B?RDpcVEZTXElVV2ViXEdhcE5ldFNlcnZlclxBU1BTZXJ2aWNlc1xMb2dpblxDb25uZWN0?=
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Request-Headers: X-Requested-With, accept, content-type
Date: Tue, 01 Sep 2015 13:05:23 GMT
Content-Length: 0

И все же Firefox блокирует запрос со следующим сообщением:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49815//Login/Connect. (Reason: missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
4b9b3361

Ответ 1

Зачастую потоки, которые я читал, предполагали несколько ненужных шагов настройки, что создавало путаницу. Это на самом деле очень просто...

Для простой цели отправки запроса кросс-сайта от клиента angular к контроллеру ASP:

  • Нет перехватчиков angular.
  • Не требуется никаких настраиваемых фильтров на стороне сервера.
  • Единственная обязательная модификация заключается в том, чтобы добавить это на сервер web.config

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

Ответ 2

Проблема в том, что некоторые браузеры пока не поддерживают подстановочный знак * для Access-Control-Allow-Headers. В частности, Firefox 69 и более ранних версий этого не делает. См. Https://bugzilla.mozilla.org/show_bug.cgi?id=1309358.

Таким образом, чтобы обеспечить ожидаемое поведение во всех браузерах, значение Access-Control-Allow-Headers вы отправляете обратно, должно явно перечислять все имена заголовков, к которым вам действительно нужно получить доступ из кода внешнего интерфейса; например, для рассматриваемого случая: Access-Control-Allow-Headers: Content-Type.

Вы можете сделать это без необходимости жестко кодировать все имена заголовков: пусть ваш код на стороне сервера примет значение Access-Control-Request-Headers запроса Access-Control-Request-Headers отправляемого браузером, и просто отобразит его в значение Access-Control-Allow-Headers ответа Access-Control-Allow-Headers ваш сервер отправляет обратно.

Или же используйте некоторую существующую библиотеку для CORS-включения вашего сервера. Вставка значения Access-Control-Request-Headers запроса Access-Control-Request-Headers значение Access-Control-Allow-Headers ответа Access-Control-Allow-Headers - это то, что большинство библиотек CORS обычно делают для вас.