Предполетный запрос не инициирован для проверки CORS

Насколько я понимаю, браузер отправляет предварительный запрос, если любое из следующих условий ложно (источник: https://developer.mozilla.org/en-US)./docs/Web/HTTP/CORS#Simple_requests):

  • Метод запроса — GET, HEAD или POST.
  • Пользовательские заголовки не устанавливаются.
  • Значение заголовка Content-Type: application/x-www-form-urlencoded, multipart/form-data или text/plain.

У меня есть веб-приложение, которое отправляет запрос GET на сервер из другого источника. Поскольку я должен отправлять файлы cookie на сервер, для свойства withCredentials установлено значение true. Заголовок Content-Type установлен на application/json. Для этого запроса браузер не запускает предварительный запрос, но должен, потому что третье условие ложно. Что может быть причиной этого? Имеет ли это какое-то отношение к незначительности заголовка Content-Type для запроса GET (поскольку тела запроса нет)?

РЕДАКТИРОВАТЬ: добавление кода запроса:

configObject = {
  'withCredentials': true,
  headers: {
    'Content-Type': 'application/json'
  }
};

function getRequest(url, dict) {
  $http.get(url, Object.assign({}, configObject)).success(function(result) {
    // on success
  }).error(function(err) {
    // on error
  });
  // return
}

person Shubham    schedule 24.12.2018    source источник
comment
Вам нужно будет опубликовать свой код запроса, если вы хотите узнать мнение других здесь, потому что похоже, что ваш реальный код не делает того, что описано в вопросе. Если код инициирует запрос из разных источников, а код, выполняющий запрос, фактически устанавливает для заголовка Content-Type значение application/json, то это обязательно приведет к тому, что браузер выполнит предварительную проверку. Всегда.   -  person sideshowbarker    schedule 24.12.2018
comment
@sideshowbarker Я сомневаюсь, что заголовок действительно установлен. Когда я проверяю запрос (на вкладке браузера «Сеть»), этот заголовок отсутствует в заголовках запроса. Сейчас добавил код.   -  person Shubham    schedule 24.12.2018
comment
Да, я не уверен, почему код использует «Object.assign({}, configObject)» в качестве второго параметра для этого вызова .get, а не просто «configObject», но я думаю, вы можете попробовать это только с '$http.get(url, configObject)'. И если это не приведет к тому, что заголовок будет установлен так, как ожидалось, то я понятия не имею. Лично я бы порекомендовал вместо этого просто использовать стандартный метод выборки…   -  person sideshowbarker    schedule 24.12.2018
comment
@sideshowbarker Это действительно была проблема. Angular удалял этот заголовок в отсутствие тела запроса. Можете ли вы опубликовать это как ответ?   -  person Shubham    schedule 26.12.2018


Ответы (1)


Если ваш интерфейсный код инициирует кросс-оригинальный запрос, а код, делающий запрос, фактически устанавливает заголовок Content-Type в application/json, то это обязательно заставит браузер выполнить предварительную проверку. Всегда.

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

Но конкретный случай, описанный в вопросе,… странный, потому что он пытается добавить заголовок Content-Type к запросуGET, а запрос GET в вопросе (как и почти все остальные запросы GET) этого не делает. нет тела запроса.

Итак, в данном случае причина сводится к тому, что Angular для вызовов $http автоматически делает что-то умное (если это неожиданно): при отсутствии тела запроса он удаляет заголовок Content-Type из запроса, что делает некоторый здравый смысл, потому что, если нет тела запроса, нет необходимости иметь заголовок, указывающий его тип носителя.

См. принятый ответ на странице https://stackoverflow.com/questions/16194442/angular-content-type-is-not-being-sent-with-http/16195104#16195104 для подтверждения этого.

Итак, если по какой-то причине вам действительно нужно включить заголовок Content-Type в запрос, не имеющий тела запроса, то решение состоит в том, чтобы либо вообще не использовать Angular $http — а вместо этого использовать, скажем, стандартный Fetch API, который позволит вы должны включить Content-Type даже для запросов, в которых отсутствует тело запроса, или же (в случае, если у вас также есть какое-то требование использовать $http Angular) передать пустое тело запроса как часть запроса $http (путем добавления data: '' к запросу).

person sideshowbarker    schedule 26.12.2018