Поле заголовка запроса Access-Control-Allow-Headers не допускается само по себе в предполетном ответе


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

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

поле заголовка запроса Access-Control-Allow-Headers не допускается Access-Control-Allow-Headers в предполетном режиме ответ

я предположил, что я мог бы сделать это:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","*")
})

или эквивалент, но это, кажется, не исправить. Я тоже конечно пробовал

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})

все равно не повезло.

13 139

13 ответов:

когда вы начнете играть с заголовками пользовательских запросов, вы получите предварительный полет CORS. Это запрос, который использует HTTP OPTIONS глагол и включает в себя несколько заголовков, один из которых является Access-Control-Request-Headers список заголовков клиент хочет включить в запрос.

вам нужно ответить на этот предварительный полет CORS с соответствующими заголовками CORS, чтобы сделать эту работу. Один из которых действительно Access-Control-Allow-Headers. Что заголовок должен содержать те же значения Access-Control-Request-Headers заголовок содержится (или более.)

https://fetch.spec.whatwg.org/#http-cors-protocol объясняет эту настройку более подробно.

Это то, что вам нужно добавить, чтобы заставить его работать.

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

браузер отправляет предварительный запрос (с параметрами типа метода), чтобы проверить, разрешен ли доступ к службе, размещенной на сервере, из браузера в другом домене. В ответ на запрос перед полетом, если вы вводите заголовки выше, браузер понимает, что можно совершать дальнейшие вызовы, и я получу действительный ответ на мой фактический вызов GET/POST. вы можете ограничить домен, к которому осуществляется доступ предоставлено с помощью Access-Control-Allow-Origin", " localhost, xvz.com-вместо * . (*предоставит доступ ко всем доменам)

эта проблема решается с

 "Origin, X-Requested-With, Content-Type, Accept, Authorization"

в частности, в моем проекте (express.js / nodejs)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  next();
});

обновление:

каждый раз об ошибке: Access-Control-Allow-Headers is not allowed by itself in preflight response ошибки, вы можете увидеть, что с chrome developer tool:
enter image description here

выше ошибка отсутствует Content-Type Так что добавьте строку Content-Type до Access-Control-Allow-Headers

принятый ответ в порядке, но у меня были трудности, чтобы понять это. Итак, вот простой пример, чтобы прояснить это.

в моем запросе ajax у меня был стандартный заголовок авторизации.

    $$(document).on('ajaxStart', function(e){
    var auth_token = localStorage.getItem(SB_TOKEN_MOBILE);
    if( auth_token ) {
        var xhr = e.detail.xhr;

        xhr.setRequestHeader('**Authorization**', 'Bearer ' + auth_token);
    }

этот код выдает ошибку в вопросе. Что мне нужно было сделать на моем сервере nodejs, так это добавить авторизацию в разрешенные заголовки:

res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');

Я просто столкнулся с этой проблемой сам, в контексте ASP.NET убедитесь, что ваш веб.конфигурация выглядит так:

  <system.webServer>
<modules>
  <remove name="FormsAuthentication" />
</modules>

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler"/>-->
  <remove name="TRACEVerbHandler" />
  <!--
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
</handlers>

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>

обратите внимание на значение разрешения для Access-Control-Allow-Headers ключ. Мне не хватало значения авторизации, эта конфигурация решает мою проблему.

очень хорошо я использовал это на проекте silex

$app->after(function (Request $request, Response $response) {
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set("Access-Control-Allow-Credentials", "true");
        $response->headers->set("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
        $response->headers->set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    });

чтобы добавить к другим ответам. У меня была та же проблема, и это код, который я использовал в своем экспресс-сервере, чтобы разрешить Вызовы REST:

  app.all('*', function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'URLs to trust of allow');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    if ('OPTIONS' == req.method) {
    res.sendStatus(200);
    } else {
      next();
    }
  });

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

EDIT: я использовал это исправление для двух отдельных серверов NodeJS express на одной машине. В итоге я решил проблему с простой прокси-сервер.

В Chrome:

поле заголовка запроса X-Requested-With не допускается Access-Control-Allow-Headers в предполетном ответе.

для меня, эта ошибка была спровоцирована пробел в URL этого вызова.

jQuery.getJSON( url, function( response, status, xhr ) {
   ...
}

res. setHeader ('Access-Control-Allow-Headers','*');

просто чтобы добавить, что вы можете поместить эти заголовки также в файл конфигурации Webpack. Я нуждался в них, как и в моем случае, когда я запускал webpack dev server.

devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Methods": "GET,HEAD,OPTIONS,POST,PUT",
      "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization"
},

эта проблема возникает, когда мы делаем собственный заголовок для запроса.Этот запрос, который использует HTTP OPTIONS и включает в себя несколько заголовков.

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

 response.header("Access-Control-Allow-Origin", "*"); // allow request from all origin
  response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");

та же проблема, с которой я столкнулся.

Я сделал простое изменение.

  <modulename>.config(function($httpProvider){
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

Я получил ошибку, указанную в OP, используя Django, React и lib django-cors-headers. Чтобы исправить это с помощью этого стека, выполните следующие действия:

в settings.py добавить ниже в часть официальная документация.

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)