当我的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代码更改为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');
Postman按预期工作:
是否可以通过XHR获得4xx响应正文和状态代码?根据HTTP 4xx上的W3C Status Code Definitions:
除了在响应HEAD请求时,服务器应该包含一个实体,其中包含错误情况的解释,以及它是暂时的还是永久的。这些状态代码适用于任何请求方法。用户代理应该向用户显示任何包含的实体。
然而,根据this discussion:
2)浏览器不显示HTTP 401响应的text / html响应主体,而是只弹出一个模态认证对话框(直到"取消"被按下)。
3)服务器不会发送具有401状态的有意义的响应正文,因为浏览器无论如何都不会显示它。
答案 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)。请注意,我在端口9000
和9001
上运行播放两次并使用播放2.2.1
。然后从9001
播放,我向9000
发出请求。