2016-11-08 3 views
4

Я пытаюсь отправить некоторые HTTP-запросы из моего приложения angular.js на свой сервер, но мне нужно решить некоторые ошибки cors.HTTP-запрос от углового отправит методом OPTIONS вместо POST

запрос HTTP равен этот образец:

functions.test = function(foo, bar) { 
    return $http({ 
     method: 'POST', 
     url: api_endpoint + 'test', 
     headers: { 
      'foo': 'value', 
      'content-type': 'application/json' 
     }, 
     data: { 
      bar:'value' 
     } 
    }); 
}; 

первого конец попытки некоторых Корс ошибки. Поэтому я реализовать следующие строки в моем сценарии сервера PHP:

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); 
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type'); 

Первая ошибка теперь устранена.

Теперь консоль разработчика (на хроме) показать мне следующие ошибки:

angular.js: 12011 OPTIONS http://localhost:8000/test (анонимный функция)

423ef03a: 1 XMLHttpRequest не может загрузить http://localhost:8000/test. Ответ на предполетной имеет недействительные HTTP код статус 400

и сетевой запрос выглядит как я ожидал (состояние 400 также ожидается):

network request

Я не могу себе представить, как решить (и как понять), почему запрос будет отправлять на localhost в качестве OPTIONS и на удаленные серверы в виде POST. Есть ли решение, как исправить эту странную вещь?

+1

Попробуйте добавить 'Принять': 'application/json' в заголовке –

+2

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

+2

Проблема заключается в том, что ответ на запрос предпросмотра ('OPTIONS') не увенчался успехом, т. Е. HTTP 400. Вот почему сбой реального (последующего) запроса. Вы должны убедиться, что ответ на запрос предполетной проверки действителен. –

ответ

3

OPTIONS запрос pre-flight request, который является частью Cross-origin resource sharing (CORS). Браузеры используют его, чтобы проверить, разрешен ли реальный запрос, который будет следовать в случае успеха, из определенного домена.

Браузеры отправляют предполетным запросов в таких случаях:

  • пользовательской HTTP-заголовки, как application/xml или application/json и т.д., используются
  • метода
  • запроса, являются исключением GET, HEAD или POST и метод POST относятся к другому типу контента, чем application/x-www-form-urlencoded, multipart/form-data или text/plain

Вы должны убедиться, что ответ на перед полетом запроса имеет следующие атрибуты:

  • успешный HTTP код статуса, т.е.200 OK
  • заголовок Access-Control-Allow-Origin: * (* позволяет запрос из любого домена, вы можете использовать любой конкретный домен, чтобы ограничить доступ здесь, конечно)

С другой стороны, сервер может отказать в просьбе CORS просто посылая ответ на перед полетом запроса со следующими атрибутами:

  • неуспехом код HTTP (то есть, кроме 2XX)
  • Успешный HTTP-код (например, 200 OK), но без какого-либо заголовка CORS (т.е. Access-Control-Allow-*)

Таким образом, в вашем случае, правильный заголовок присутствует, вы просто должны убедиться, что код состояния HTTP в перед полетом ответа является 200 OK ,

Для получения более подробной информации см. documentation on Mozilla Developer Network или, например, HTML5Rocks' CORS tutorial.

0

У меня возникла аналогичная проблема с написанием приложения Angular 2, которое использует сервер NODE для API.

Поскольку я развиваюсь на своей локальной машине, я постоянно сталкиваюсь с проблемами Cross Origin Header, когда я буду пытаться использовать POST для API из моего приложения Angular.

Установка заголовков (на сервере узлов), как показано ниже, для запросов GET, но мои запросы PUT сохраняли отправку пустых объектов в базу данных.

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); 
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, 
Origin, Authorization, Accept, Client-Security-Token, Accept- 
Encoding, X-Auth-Token, content-type'); 

После прочтения Dawid Ferenczy's post, я понял, что предполетной запрос отправлял ТпустуюУ на мой сервер, и поэтому мои записи БД были пусты, так что я добавил эту строку на сервере УЗЕЛ JS:

if (req.method == "OPTIONS") 
    { 
     res.writeHead(200, {"Content-Type": "application/json"}); 
     res.end(); 
    } 

Итак, теперь мой сервер игнорирует запрос PREFLIGHT (и возвращает статус 200, чтобы браузер знал, что все в порядке), и таким образом реальный запрос может пройти, и я получаю реальные данные, отправленные в мою БД!

Смежные вопросы