Non-record based Json calls across Domains with Ext
Ext General 1 Comment »From a forum question I posted at Ext: http://extjs.com/forum/showthread.php?t=5430
I am trying to make a call to a webpage that returns a json object that is hierarchical in nature and not record based so as far as I am aware, jsonreader / datareader are not suitable.
The Server returns something looking like this:
1: (
2: {
3: children: [
4: {
5: id : "1",
6: name : "Dim Item 1",
7: children : [
8: {
9: id : "1.0",
10: name : "Dim Item 1.0"
11: },
12: {
13: id : "1.1",
14: name : "Dim Item 1.1"
15: }
16: ]
17: }
18: ]
19: }
20: );
Where each item can have children in a hierarchy. (I am not trying to use this data with the Ext Tree by the way)
To complicate matters the server providing the data is hosted on a different port, so I have to use the Ext.data.ScriptTagProxy to get the data, which is successful. I had a few teething problems until I realized you had to wrap the json object returned with the callback function name.
However, with my limited understanding and debugging the code, the Ext.data.ScriptTagProxy requires a reader to be supplied, but all I want in this instance is the object.
This is the client side code:
1: function GetData()
2: {
3: var url = "http://localhost:4855/largeJasonHierarchy.aspx";
4: var conn = new Ext.data.ScriptTagProxy({
5: url: url
6: });
7:
8: var reader = new Ext.data.ObjectReader();
9: conn.load({},reader,GotData);
10: }
11:
12:
13:
14: function GotData(x)
15: {
16: alert(x);
17: }
As a reader is required, I had to hack a copy of the jsonReader to create a ObjectReader that simply returns the object and does not process it.
ObjectReader.js
1: Ext.data.ObjectReader = function(meta, recordType){
2: Ext.data.ObjectReader.superclass.constructor.call(this, meta, recordType);
3: };
4: Ext.extend(Ext.data.ObjectReader, Ext.data.DataReader, {
5:
6: readRecords : function(o){
7: return o;
8: }
9: });
This all works, but I can’t help feeling like I’ve missed something crucial in the Ext library. Could someone with more experience than me confirm I have gone down the correct route, or let me know if there is a better way of getting json objects back in any format. (cross domain of course)
One concern, is that I have seen articles saying that any json data passed back from a server should be run through a regex parser to check that there are no functions /etc being injected in the data packets (anti-hacking and the likes) I’m not yet sure how I would fit this into the ObjectReader.
Thanks for any help.
Response by Animal, notice the way he has used the Ext override to override the default implementation on ScriptTagProxy.handleResponse.
As it stands, that’s the best way.
I think an enhancement request could be in order. If you don’t pass a reader, it should skip the call to reader.readRecords, and just call your callback passing the returned object.
That way, the following would work.
1: conn.load({},null,GotData);
by adding:
1: Ext.override(Ext.data.ScriptTagProxy, {
2: handleResponse : function(o, trans){
3: this.trans = false;
4: this.destroyTrans(trans, true);
5: var result;
6: if (trans.reader) {
7: try {
8: result = trans.reader.readRecords(o);
9: }catch(e){
10: this.fireEvent("loadexception", this, o, trans.arg, e);
11: trans.callback.call(trans.scope||window, null, trans.arg, false);
12: return;
13: }
14: } else {
15: result = o;
16: }
17: this.fireEvent("load", this, o, trans.arg);
18: trans.callback.call(trans.scope||window, result, trans.arg, true);
19: }
20: });