我是在ExtJs4的RESTFul Store example上构建的,当添加或删除请求失败时,我希望我的脚本能够显示REST服务器提供的错误。我已经设法获得了请求的成功状态(请参阅下面的代码),但是如何获得响应提供的消息呢?
商店:
var store = Ext.create('Ext.data.Store', {
model: 'Users',
autoLoad: true,
autoSync: true,
proxy: {
type: 'rest',
url: 'test.php',
reader: {
type: 'json',
root: 'data',
model: 'Users'
},
writer: {
type: 'json'
},
afterRequest: function(request, success) {
console.log(success); // either true or false
},
listeners: {
exception: function(proxy, response, options) {
// response contains responseText, which has the message
// but in unparsed Json (see below) - so I think
// there should be a better way to reach it than
// parse it myself
console.log(proxy, response, options);
}
}
}
});
典型的REST响应:
"{"success":false,"data":"","message":"VERBOSE ERROR"}"
也许我做的一切都错了,所以任何建议我都很感激。
发布于 2011-09-26 00:07:28
我假设您的服务遵循REST原则,并使用2xx
以外的状态码来处理不成功的操作。但是,对于没有返回status OK 2xx
的响应,Ext不会解析响应正文。在这种情况下,exception/response对象(传递给“exception”事件侦听器)所提供的只是response.statusText
中的HTTP status消息。
因此,您必须自己将responseText解析为JSON。这并不是真正的问题,因为它可以用一行代码来完成。
var data = Ext.decode(response.responseText);
根据您的编码风格,您可能还希望添加一些错误处理和/或区分“预期的”和“意外的”HTTP错误状态代码。(这来自Ext.data.reader.Json)
getResponseData: function(response) {
try {
var data = Ext.decode(response.responseText);
}
catch (ex) {
Ext.Error.raise({
response: response,
json: response.responseText,
parseError: ex,
msg: 'Unable to parse the JSON returned by the server: ' + ex.toString()
});
}
return data;
},
此行为的原因可能是因为REST代理类不是数据包中的第一类成员。它派生自一个公共基类,这个基类还定义了标准AJAX (或JsonP)代理的行为,这些代理只对通信通道错误使用HTTP状态码。因此,在这种情况下,他们不会期望来自服务器的任何可解析消息。相反,指示应用程序错误的服务器响应将返回HTTP status OK,以及您的问题中发布的JSON响应(使用success:"false"
和message:"[your error message]"
)。
有趣的是,REST服务器可以返回具有非2xx状态的响应,以及具有有效JSON响应(在Ext术语中)和success属性设置为'true‘的响应正文。异常事件仍然会被激发,并且响应体不会被解析。这种设置没有多大意义--我只想指出HTTP状态代码中的“成功”与正文中的success属性之间的区别(前者优先于后者)。
更新
对于更透明的解决方案,您可以扩展(或覆盖) Ext.data.proxy.Rest:这将把成功值从false
更改为true
,然后调用标准的processResponse实现。这将模拟“标准”的Ext行为并解析responseText。当然,这将期望得到一个标准的JSON响应,就像您最初的success:"false"
帖子中所概述的那样(否则会失败)。这还没有经过测试,if表达式应该更智能一些。
Ext.define('Ext.ux.data.proxy.Rest', {
extend: 'Ext.data.proxy.Rest',
processResponse: function(success, operation, request, response, callback, scope){
if(!success && typeof response.responseText === 'string') { // we could do a regex match here
var args = Array.prototype.slice.call(arguments);
args[0] = true;
this.callParent(args);
} else {
this.callParent(arguments);
}
}
})
https://stackoverflow.com/questions/7546469
复制相似问题