| Summary: Working with JSON |
| Author: Patrick Donelan |
| Published: 2007-09-25 |
| Ext Version: 1.1 |
Languages: English Chinese
|
Contents |
Working with JSON Say you have a javascript object that looks like:
var obj = { prop1: "a0~`!@#$%^&*()-_+={}[]|\\:;\"',.?/", prop2: ['x','y'], prop3: { nestedProp1: 'abc', nestedProp2: 456 } }
This article discusses how you can turn your object into JSON and send it to your server.
URL Encoding with Ext.urlEncode The first method we want to look at is Ext.urlEncode (and its decoding partner Ext.urlDecode). Ext.urlEncode() doesn't actually work with JSON at all, what it does is convert a simple object into name/value pairs suitable for use in an HTTP GET or POST request. I say simple here because urlEncode only looks at first-level properties - arrays are ok but nested objects will be ignored. For example:
Ext.urlEncode(obj) == "prop1=a0~%60!%40%23%24%25%5E%26*()-_%2B%3D%7B%7D%5B%5D%7C%5C%3A%3B%22'%2C.%3F%2F&prop2=x&prop2=y"
This is handy for crafting requests because you can build up your params as a native javascript object and then urlEncode it just before sending.
For example, you can appended this string to the end of a url as a GET request:
http://myurl.com?prop1=a0~%60!%40%23%24%25%5E%26*()-_%2B%3D%7B%7D%5B%5D%7C%5C%3A%3B%22'%2C.%3F%2F&prop2=x&prop2=y
prop1 a0~`!@#$%^&*()-_+={}[]|\:;"',.?/
prop2 x
prop2 y
Or you can send the string as the contents of a POST request:
http://myurl.com
prop1=a0~%60!%40%23%24%25%5E%26*()-_%2B%3D%7B%7D%5B%5D%7C%5C%3A%3B%22'%2C.%3F%2F&prop2=x&prop2=y
That's all well and good, but what you came here to see was how to send and receive JSON. To find out how, read on!
Encoding JSON with Ext.encode Ext.encode() (and its decoding equivalent Ext.decode) converts a complex object into a string of JSON For example:
Ext.encode(obj) == '{"prop1":"a0~`!@#$%^&*()-_+={}[]|\\:;\"\',.?/","prop2":["x","y"],"prop3":{"nestedProp1":"abc","nestedProp2":456}}'
Unlike before when we converted a simple object into a series of name/value pairs, your object has now been converted into a single parameter. The idea is that you now send it to the server as part of a name/value pair, and let the server JSON decode it. If you're only sending the one JSON string, you would probably call your parameter json.
To turn your JSON into a name/value pair suitable for a GET/POST request, you can encode it manually:
encodeURIComponent(Ext.encode(obj)) == "%7B%22prop1%22%3A%22a0~%60!%40%23%24%25%5E%26*()-_%2B%3D%7B%7D%5B%5D%7C%5C%5C%3A%3B%5C%22'%2C.%3F%2F%22%2C%22prop2%22%3A%5B%22x%22%2C%22y%22%5D%2C%22prop3%22%3A%7B%22nestedProp1%22%3A%22abc%22%2C%22nestedProp2%22%3A456%7D%7D"
And create a GET request as:
"http://url.com?json=" + encodeURIComponent(Ext.encode(obj))
Or use as the body of a POST request:
"json=" + encodeURIComponent(Ext.encode(obj))
Or better yet use our friend urlEncode():
Ext.urlEncode({ json: Ext.encode(obj)}) == "json=%7B%22prop1%22%3A%22a0~%60!%40%23%24%25%5E%26*()-_%2B%3D%7B%7D%5B%5D%7C%5C%5C%3A%3B%5C%22'%2C.%3F%2F%22%2C%22prop2%22%3A%5B%22x%22%2C%22y%22%5D%2C%22prop3%22%3A%7B%22nestedProp1%22%3A%22abc%22%2C%22nestedProp2%22%3A456%7D%7D"
And use this in GET/POST requests as before. Either way, the server will transparently URIComponent decode the param, giving you:
{"prop1":"a0~`!@#$%^&*()-_+={}[]|\\:;\"',.?/","prop2":["x","y"],"prop3":{"nestedProp1":"abc","nestedProp2":456}}
Which you can then JSON decode to access the data.
Sending JSON with Ext.Ajax.request As of Ext 1.1, you can easily create manual Ajax-style requests by using Ext.Ajax.request(). This method accepts a configuration object which, among other things, allows you to define the params to use for the request:
params {Object/String/Function} (Optional) An object containing properties which are used as parameters to the request, a url encoded string or a function to call to get either.
If you pass in an object, Ext.Ajax.request calls Ext.urlEncode() to turn it into a series of name/value pairs (as usual ignoring nested objects).
var req = Ext.Ajax.request({ url: "/ws/search.pl", params: obj, method: 'GET', disableCaching: false })
Request goes to:
/ws/search.pl?prop1=a0~%60!%40%23%24%25%5E%26*()-_%2B%3D%7B%7D%5B%5D%7C%5C%3A%3B%22'%2C.%3F%2F&prop2=x&prop2=y
And the server sees:
prop1 a0~`!@#$%^&*()-_+={}[]|\:;"',.?/
prop2 x
prop2 y
If we use POST instead (the default when params are specified), the same thing happens, except that the name/value pairs are passed as the body of the POST request.
To send JSON to the server, we need to use Ext.encode() to convert our data object into a string of JSON. Ext.Ajax.request() expects a url encoded string, so you can either encode it yourself using encodeURIComponent() or better yet turn your json string into a simple object and have Ext.Ajax.request() do the encoding for you:
var req = Ext.Ajax.request({ url: "/ws/search.pl", params: {json: Ext.encode(obj)}, disableCaching: false })
As before, the server will see:
{"prop1":"a0~`!@#$%^&*()-_+={}[]|\\:;\"',.?/","prop2":["x","y"],"prop3":{"nestedProp1":"abc","nestedProp2":456}}
Which you can then JSON decode to access the data.
See also