简体   繁体   English

AngularJS 1.2.14 $ http POST错误响应正文为空

[英]AngularJS 1.2.14 $http POST Error Response Body Empty

UPDATE Mar 21 After more investigation it looks like this is also showing a Play framework bug an XHR limitation on error status: Play 2.2.1 SimpleResult 4xx Response Body Possible via CORS XHR? 更新3月21日经过更多调查,似乎还显示 了Play框架错误 ,错误状态的XHR限制: 播放2.2.1 SimpleResult 4xx响应正文可以通过CORS XHR吗? That, or the RESTfulness I seek is not possible with 401 codes. 那,或者我寻求的RESTful是401代码无法实现的。

Still an issue in both spaces since a 401 gets a 0 status code in Angular $http as below. 由于401在Angular $ http中的状态代码为0,如下所示,这在两个空格中仍然是一个问题。 So much for RESTfulness! RESTfulness非常重要! All I want to do is provide a response body for 401 Unauthorized. 我要做的只是为401未经授权提供回复正文。 From the W3C page on 4xx : "User agents SHOULD display any included entity to the user." 在4xxW3C页面上 :“用户代理应向用户显示任何包含的实体。”

UPDATE Mar 20 更新3月20日

Further investigation points to an issue within XMLHttpRequest itself, but please let me know if I am missing something below. 进一步的调查表明XMLHttpRequest本身存在问题,但是如果我缺少以下内容,请告诉我。 I am spitting out the raw XHR object inside the xhr.onreadystatechange() callback as defined inside Angular's createHttpBackend(): 我在Angular的createHttpBackend()中定义的xhr.onreadystatechange()回调中吐出了原始XHR对象:

角源mod到控制台

When I log in with a known good email and password, everything works fine: 使用已知的正确电子邮件地址和密码登录时,一切正常:

200 OK,带有响应JSON

But the same XHR object for a 400 Bad Request (wrong password) has an empty response but more importantly status=0, which from Mozilla docs denotes the request was never sent (but I am seeing my API server get the request and do a DB lookup, as Postman works as above): 但是,对于一个400错误请求(错误密码)的同一个XHR对象,响应为空,但更重要的是status = 0,这从Mozilla docs表示该请求从未发送过(但是我看到我的API服务器收到了请求并执行了数据库查找,因为邮递员的工作如上所述):

在此处输入图片说明

What gives? 是什么赋予了? How does Postman get a response but XMLHttpRequest on latest Chrome and Firefox is confused? Postman如何获​​得响应,但最新的Chrome和Firefox上的XMLHttpRequest却感到困惑?

I am sending a POST request using $http and getting conflicting responses in the browser (Chrome and FF), and Postman. 我正在使用$ http发送POST请求,并在浏览器(Chrome和FF)和Postman中收到冲突的响应。 Postman works fine and has the body, but it looks like angular is "cleaning" up some response codes to handle weirdness on Android browsers when templates are cached, but I can't pinpoint the spot in $httpBackend where the raw XHR is happening to intercept the response body--maybe that's because the XHR is blocking/canceling the response? 邮递员工作得很好并且有身体,但是当角度缓存模板时,角度似乎正在“清理”一些响应代码以处理Android浏览器上的怪异,但我无法查明$ httpBackend中原始XHR发生的位置拦截响应主体-也许是因为XHR正在阻止/取消响应? Because security? 因为安全? I do not have any interceptors, either. 我也没有拦截器。

The "happy path" login works fine and I get matching 200 OK responses in the console/firebug, but 400 Bad Request doesn't have a response body. “快乐路径”登录工作正常,并且在控制台/萤火虫中获得匹配的200 OK响应,但是400 Bad Request没有响应正文。

CORS is configured on nginx (see http://enable-cors.org/server_nginx.html ) and since the happy login success works the setup is functional. 在Nginx上配置了CORS(请参阅http://enable-cors.org/server_nginx.html ),并且由于成功登录成功,因此可以进行设置。

My call: 我的电话:

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 is modifying the error code so the browser and angular do not agree: Angular正在修改错误代码,因此浏览器和angular不一致:

angular修改XHR响应中的http代码

When I send the same request via Postman, the 400 Bad Request code is the same, but the body is also a json string, as expected. 当我通过邮递员发送相同的请求时,400错误的请求代码是相同的,但是主体还是一个json字符串,正如预期的那样。

Why is this not available via $http CORS inside the onLoginError() callback? 为什么在onLoginError()回调中无法通过$ http CORS使用此功能?

邮递员工作得很好

The problem I think is you are sending the POST body as JSON, rather it need to send as query param. 我认为问题是您将POST主体作为JSON发送,而需要作为查询参数发送。 Try this change 试试这个变化

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

This will make your body as query params. 这将使您的身体成为查询参数。 Also don't forget to include jquery.js library 也不要忘记包含jquery.js

The issue ended up being with my api server code. 问题最终出在我的api服务器代码上。 My app was only sending Content-Type headers but I thought nginx would be able to serve up Allow-Origin headers and keep the app ignorant of any headers. 我的应用仅发送Content-Type标头,但我认为nginx将能够提供Allow-Origin标头,并使应用不知道任何标头。

See Play 2.2.1 SimpleResult 4xx Response Body Possible via CORS XHR? 请参见播放2.2.1 SimpleResult 4xx响应主体是否可以通过CORS XHR? for the answer. 寻找答案。 It's the Play Scala .withHeaders() part that fixed the issue via CORS. Play Scala .withHeaders()部分通过CORS解决了该问题。

Wonder if there's a way to have nginx handle all headers, maybe my proxy_pass section is not done right. 想知道是否有办法让Nginx处理所有标头,也许我的proxy_pass部分没有正确完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM