ExtJs 4の RESTFulストアの例 に基づいて構築しています。追加または削除リクエストが失敗したときに、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"}"
おそらく私はそれをすべて間違っているので、アドバイスをいただければ幸いです。
あなたのサービスはRESTの原則に従い、失敗した操作には2xx
以外のHTTPステータスコードを使用すると思います。ただし、Extは応答本文を解析しますnotステータスを返さない応答の場合OK2xx
。例外/応答オブジェクト(「exception」イベントリスナーに渡される)doesこのような場合に提供されるのは、HTTPステータスメッセージのみです。 response.statusText
。
したがって、JSONへのresponseTextを自分で解析する必要があります。これは1行で実行できるため、実際には問題にはなりません。
var data = Ext.decode(response.responseText);
コーディングスタイルによっては、エラー処理を追加したり、「予期された」HTTPエラーステータスコードと「予期されなかった」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ステータスOK、および質問に投稿されたJSON応答(success:"false"
およびmessage:"[your error message]"
を使用)で返されます。
興味深いことに、RESTサーバーは、2xx以外のステータスの応答と、有効なJSON応答(Ext用語)およびsuccessプロパティが「true」に設定された応答本文を返す可能性があります。例外イベントは引き続き発生し、応答本文は解析されません。この設定はあまり意味がありません。本文の成功プロパティと比較したHTTPステータスコードの観点からの「成功」の違いを指摘したいだけです(前者が後者よりも優先されます)。
より透過的なソリューションの場合、Ext.data.proxy.Restを拡張(またはオーバーライド)できます。これにより、成功値がfalse
からtrue
に変更され、標準のprocessResponse実装が呼び出されます。これにより、「標準」のExt動作がエミュレートされ、responseTextが解析されます。もちろん、これは、元の投稿でsuccess:"false"
で概説されている標準のJSON応答を期待します(または失敗します)。ただし、これはテストされておらず、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);
}
}
})