通过CORS XHR播放2.2.1 SimpleResult 4xx响应主体?

时间:2014-03-21 22:20:25

标签: scala https xmlhttprequest playframework-2.2

当我的API提供4xx http响应代码时,我正在尝试发送JSON响应正文。当代码为200时,一切正常,但更改为4xx,没有收到正文。 Chrome的Postman显示身体反应,但XHR(Chrome,FF)没有。

是否可能将响应体放入XHR并且nginx CORS正确设置(我将其设置为简单回显... Allow-Origin:$ http_origin)?我有一个nginx作为127.0.0.1:9001上实际API服务器的proxy_pass。当我发送已知凭据时,CORS和Allow-Origin都可以正常工作200 OK。如果我只是使用错误的密码,我会在Firebug中看到错误状态代码,但是XHR对象(也是jQuery' s $ .ajax)的Status = 0,即使请求到达API服务器。

至少我希望能够在XHR对象中获取4xx状态代码,这样我至少可以显示某些4xx代码的一般信息而不是通用的#34;它没有工作"这也是不可用的,我总是得到status = 0,即使API被命中并且在nginx中记录了正确的响应代码。

更新3/23 Javascript XHR代码:

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://arinna-api/v1/401', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
    // do something to response
    console.log(this);
};

播放框架代码以返回状态200 OK JSON内容类型响应正文:

SimpleResult(
  header = ResponseHeader(200, Map(CONTENT_TYPE -> "application/json")),
  body = Enumerator("{\"error\":\"invalid grant\"}".getBytes())
)

200 OK按预期工作:

HTTP 200 OK Works but is not REST

将HTTP代码更改为401会导致XMLHttpRequest不接收响应正文(xhr.status也是0而不是401):

SimpleResult(
  header = ResponseHeader(401, Map(CONTENT_TYPE -> "application/json")),
  body = Enumerator("{\"error\":\"invalid grant\"}".getBytes())
)

xhr.send('username=username&password=badpassword&grant_type=password&client_id=mobile_platform');

HTTP 401 no body parsed from response

Postman按预期工作:

enter image description here

是否可以通过XHR获得4xx响应正文和状态代码?根据HTTP 4xx上的W3C Status Code Definitions

  

除了在响应HEAD请求时,服务器应该包含一个实体,其中包含错误情况的解释,以及它是暂时的还是永久的。这些状态代码适用于任何请求方法。用户代理应该向用户显示任何包含的实体。

然而,根据this discussion

  

2)浏览器不显示HTTP 401响应的text / html响应主体,而是只弹出一个模态认证对话框(直到"取消"被按下)。

     

3)服务器不会发送具有401状态的有意义的响应正文,因为浏览器无论如何都不会显示它。

1 个答案:

答案 0 :(得分:1)

以下代码按预期运行:

<强> Application.scala

object Application extends Controller {

  def index = Action { request =>
    Ok(views.html.index())
  }

  def indexPost = Action { request =>
    Unauthorized("test").withHeaders(ACCESS_CONTROL_ALLOW_ORIGIN -> "*")
  }
}

<强> routes

GET    /   controllers.Application.index
POST   /   controllers.Application.indexPost

<强> index.html.scala

@()

@main("Welcome to Play 2.1") {
  <script type="text/javascript">
      var xhr = new XMLHttpRequest();
      xhr.open('POST', 'http://localhost:9000/');
      xhr.onload = function () {
      console.log(this);
    };
    xhr.send();
  </script>
}

文本"test"显示在回复中(Opera,Chrome和Firefox)。请注意,我在端口90009001上运行播放两次并使用播放2.2.1。然后从9001播放,我向9000发出请求。