Ext JS - Learning Center

Manual:Core:Working with JSON

From Learn About the Ext JavaScript Library

Revision as of 15:56, 22 August 2009 by Rhiokim-37383 (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Summary: Working with JSON
Author: Patrick Donelan
Published: 2007-09-25
Ext Version: 1.1
Languages: en.png English cn.png Chinese kr.png Korean

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"
  • Notice that prop3 is ignored
  • Notice that all special characters are encoded (urlEncode() uses encodeURIComponent() internally)

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:

  • Request goes to:
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
  • And the server would transparently decode the URIComponent encoding to give you:
prop1	a0~`!@#$%^&*()-_+={}[]|\:;"',.?/
prop2	x
prop2	y

Or you can send the string as the contents of a POST request:

  • Request goes to:
http://myurl.com
  • With POST body:
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 see the same data as in the GET request

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}}'
  • Notice that nested properties are included now

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 don't disable disableCaching, Ext will add a unique _dc cache-buster param
  • It's hopefully obvious to you by now that as always with Ext.urlEncode(), you're not passing JSON to the server, only a series of name/value pairs.

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