AngularJS 1.2.14 $http POST Тело ответа об ошибке пусто

ОБНОВЛЕНИЕ 21 марта. После дополнительных исследований выяснилось, что это также показывает ошибку платформы Play ограничение XHR на статус ошибки: Воспроизвести 2.2.1 Тело ответа SimpleResult 4xx возможно через CORS XHR? Это или RESTfulness, который я ищу, не возможно с кодами 401.

Все еще проблема в обоих пространствах, поскольку 401 получает код состояния 0 в Angular $http, как показано ниже. Так много для RESTfulness! Все, что я хочу сделать, это предоставить тело ответа для 401 Unauthorized. На странице W3C на 4xx: "Пользовательские агенты ДОЛЖНЫ отображать все включенные сущность пользователю».

ОБНОВЛЕНИЕ от 20 марта

Дальнейшее расследование указывает на проблему в самом XMLHttpRequest, но, пожалуйста, дайте мне знать, если я что-то упустил ниже. Я выплевываю необработанный объект XHR внутри обратного вызова xhr.onreadystatechange(), как определено внутри Angular createHttpBackend():

модификация углового исходного кода для консоли

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

200 OK с ответом JSON

Но тот же объект XHR для 400 Bad Request (неправильный пароль) имеет пустой ответ, но, что более важно, статус = 0, что из документов Mozilla означает, что запрос никогда не был отправлен (но я вижу, что мой сервер API получает запрос и выполняет БД поиск, поскольку Postman работает, как указано выше):

введите здесь описание изображения

Что дает? Как Postman получает ответ, но XMLHttpRequest в последних версиях Chrome и Firefox запутан?

Я отправляю запрос POST с помощью $http и получаю противоречивые ответы в браузере (Chrome и FF) и Postman. Почтальон работает нормально и имеет тело, но похоже, что angular «очищает» некоторые коды ответов для обработки странностей в браузерах Android, когда шаблоны кешируются, но я не могу точно определить место в $httpBackend, где происходит необработанный XHR. перехватить тело ответа - может быть, это потому, что XHR блокирует/отменяет ответ? Потому что безопасность? У меня тоже нет перехватчиков.

Вход в систему «счастливый путь» работает нормально, и я получаю соответствующие 200 ответов OK в консоли / firebug, но 400 Bad Request не имеет тела ответа.

CORS настроен на nginx (см. http://enable-cors.org/server_nginx.html). ) и, поскольку работает счастливый успешный вход в систему, установка работает.

Мой вызов:

var onLoginSuccess = function(data, status, headers, config){
  console.log('[onLoginSuccess]')
  console.log(data)
  console.log(status)
  console.log(headers)
  console.log(config)
}

var onLoginError = function(data, status, headers, config){
  console.log('[onLoginError]')
  console.log(data)
  console.log(status)
  console.log(headers)
  console.log(config)
}

var loginObj = {
  'username':   $scope.username,
  'password':   $scope.password,
  'grant_type': 'password',
  'client_id':  'web'
}

var doLogin = $http({
  method: 'POST',
  url: 'https://api/v1/token',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  transformRequest: function(obj) {
    var str = [];
    for(var p in obj) {
      str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
    }
    return str.join('&');
  },
  data: loginObj,
  responseType: 'json'
})

doLogin.then(
  onLoginSuccess,
  onLoginError
)

Angular изменяет код ошибки, поэтому браузер и angular не согласны:

angular изменяет http-коды из ответа XHR

Когда я отправляю тот же запрос через Postman, код 400 Bad Request такой же, но тело также представляет собой строку json, как и ожидалось.

Почему это недоступно через $http CORS внутри обратного вызова onLoginError()?

почтальон работает нормально


person notbrain    schedule 19.03.2014    source источник
comment
Может быть связано с этой проблемой с 401 ответом, с которой я также столкнулся .   -  person sinelaw    schedule 19.03.2014


Ответы (2)


Я думаю, проблема в том, что вы отправляете тело POST как JSON, а не как параметр запроса. Попробуйте это изменение

var loginObj = $.param({
  'username':   $scope.username,
  'password':   $scope.password,
  'grant_type': 'password',
  'client_id':  'web'
});

Это сделает ваше тело параметрами запроса. Также не забудьте подключить jquery.js библиотеку

person BKM    schedule 19.03.2014
comment
TransformRequest уже делает это, нет необходимости использовать jQuery. - person notbrain; 19.03.2014

Проблема оказалась с моим кодом сервера API. Мое приложение отправляло только заголовки Content-Type, но я думал, что nginx сможет обслуживать заголовки Allow-Origin и держать приложение в неведении о любых заголовках.

См. Игра 2.2. 1 Тело ответа SimpleResult 4xx Возможно через CORS XHR? для ответа. Это часть Play Scala .withHeaders(), которая устранила проблему через CORS.

Интересно, есть ли способ заставить nginx обрабатывать все заголовки, возможно, мой раздел proxy_pass сделан неправильно.

person notbrain    schedule 29.03.2014