【问题标题】:AngularJS 1.2.14 $http POST Error Response Body EmptyAngularJS 1.2.14 $http POST 错误响应正文为空
【发布时间】:2014-04-25 01:06:09
【问题描述】:

3 月 21 日更新 经过更多调查,看起来这也显示了 一个 Play 框架错误一个 XHR 对错误状态的限制: Play 2.2.1 SimpleResult 4xx Response Body Possible via CORS XHR? 那个,或者我寻求的 RESTful 是不可能用 401 代码实现的。

这两个空间仍然存在问题,因为 401 在 Angular $http 中获得 0 状态代码,如下所示。安息吧!我要做的就是为 401 Unauthorized 提供响应正文。来自W3C page on 4xx:“用户代理应该向用户显示任何包含的实体。”

3 月 20 日更新

进一步调查指出 XMLHttpRequest 本身存在问题,但如果我在下面遗漏了什么,请告诉我。我在 Angular 的 createHttpBackend() 中定义的 xhr.onreadystatechange() 回调中吐出原始 XHR 对象:

当我使用已知正确的电子邮件和密码登录时,一切正常:

但是对于 400 错误请求(密码错误)的相同 XHR 对象有一个空响应,但更重要的是状态 = 0,这来自 Mozilla 文档表示该请求从未发送(但我看到我的 API 服务器收到请求并且做一个数据库查找,就像 Postman 的工作方式一样):

什么给了? Postman 怎么得到响应,但最新 Chrome 和 Firefox 上的 XMLHttpRequest 却是一头雾水?

我正在使用 $http 发送一个 POST 请求,并在浏览器(Chrome 和 FF)和 Postman 中得到冲突的响应。 Postman 工作正常并且有主体,但看起来 Angular 正在“清理”一些响应代码以在缓存模板时处理 Android 浏览器上的怪异问题,但我无法确定 $httpBackend 中发生原始 XHR 的位置拦截响应体——也许是因为 XHR 阻止/取消了响应?因为安全?我也没有拦截器。

“快乐路径”登录工作正常,我在控制台/萤火虫中得到匹配的 200 OK 响应,但 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 不一致:

当我通过 Postman 发送相同的请求时,400 Bad Request 代码是相同的,但正文也是一个 json 字符串,正如预期的那样。

为什么这不能通过 onLoginError() 回调中的 $http CORS 获得?

【问题讨论】:

标签: javascript angularjs cors playframework-2.2 angular-http


【解决方案1】:

问题最终出在我的 api 服务器代码上。我的应用只发送 Content-Type 标头,但我认为 nginx 能够提供 Allow-Origin 标头并让应用不知道任何标头。

请参阅Play 2.2.1 SimpleResult 4xx Response Body Possible via CORS XHR? 以获取答案。 Play Scala .withHeaders() 部分通过 CORS 解决了该问题。

想知道是否有办法让 nginx 处理所有标头,也许我的 proxy_pass 部分没有正确完成。

【讨论】:

    【解决方案2】:

    我认为问题是您将 POST 正文作为 JSON 发送,而不是它需要作为查询参数发送。试试这个改变

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

    这将使您的身体成为查询参数。也不要忘记包含jquery.js library

    【讨论】:

    • transformRequest 已经这样做了,不需要使用 jQuery。
    猜你喜欢
    • 2014-04-09
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2017-10-28
    相关资源
    最近更新 更多