| Summary: Working with JSON |
| Author: Patrick Donelan |
| Published: 2007-09-25 |
| Ext Version: 1.1 |
Languages: English Chinese Korean
|
Contents |
Допустим, вы имеете javascript-объект, который выглядит так:
var obj = { prop1: "a0~`!@#$%^&*()-_+={}[]|\\:;\"',.?/", prop2: ['x','y'], prop3: { nestedProp1: 'abc', nestedProp2: 456 } }
Эта статья обсуждает то, как вы можете перевести ваш объект в JSON и отправить его на ваш сервер.
Первый метод, на который мы желаем обратить внимание - это Ext.urlEncode (и его декодирующий партнер Ext.urlDecode). Ext.urlEncode() в действительности не работает с JSON вообще, все что она делает - это конвертация простого объекта в набор пар имя/значение, подходящих для использования в HTTP GET или POST-запросах. Я говорю здесь простой объект, потому что urlEncode смотрит только на свойства первого уровня - массивы разрешены,но вложенные объекты будет проигнорированны. Например:
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"
Это удобно для разработки запросов, потому что вы можете указывать параметры как естественный javascript-объект и затем делать urlEncode перед самой отправкой.
Например, вы можете прикреплять эту строку в конец url как к GET-запросу:
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
Или вы можете отправить строку, как содержимое POST-запроса:
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
Это все отлично и хорошо, но то, почему вы сюда пришли - это посмотреть, как отправлять и получать JSON. Чтобы узнать как - читайте дальше!
Ext.encode() (и ее декодирующий эквивалент Ext.decode) конвертирует составной объект в строку JSON Например:
Ext.encode(obj) == '{"prop1":"a0~`!@#$%^&*()-_+={}[]|\\:;\"\',.?/","prop2":["x","y"],"prop3":{"nestedProp1":"abc","nestedProp2":456}}'
В отличии от рассмотренного выше, когда мы конвертировали простой объект в серию пар имя/значение, ваш объект теперь сконвертирован в один параметр. Идея заключается в том, что теперь вы посылаете его как часть пары имя/значение и позволяете серверу декодировать JSON. Если вы посылаете только JSON-строку, то, возможно, вы назовете ваш параметр json.
Для превращения вашего JSON в пару имя/значение, подходящую для GET/POST-запросов, вы можете кодировать его самостоятельно:
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"
И создать GET-запрос так:
"http://url.com?json=" + encodeURIComponent(Ext.encode(obj))
Или использовать тело POST-запроса:
"json=" + encodeURIComponent(Ext.encode(obj))
Или еще лучше - вы можете использовать нашего друга 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"
Используйте это в GET/POST-запросах, как показано выше. В любом случае, сервер прозрачно декодирует параметры, вернув вам строку:
{"prop1":"a0~`!@#$%^&*()-_+={}[]|\\:;\"',.?/","prop2":["x","y"],"prop3":{"nestedProp1":"abc","nestedProp2":456}}
Которую вы можете затем JSON-декодировать для доступа к данным.
Начиная с Ext 1.1, вы можете легко создавать ручные запросы в стиле Ajax, используя Ext.Ajax.request(). Этот метод принимает конфигурационный объект среди прочих, позволяя вам определить параметры для использования в запросе:
params {Object/String/Function} (Необязательное) Объект, содержащий свойства, которые будут использоваться как параметры запроса, url-кодированная строка, или функция обратного вызова для получения параметров.
Если вы передаете объект, Ext.Ajax.request вызывает Ext.urlEncode() для превращения его в серию пар имя/значение(как обычно пропуская вложенные объекты).
var req = Ext.Ajax.request({ url: "/ws/search.pl", params: obj, method: 'GET', disableCaching: false })
Запрос отправляется на:
/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
И сервер видит:
prop1 a0~`!@#$%^&*()-_+={}[]|\:;"',.?/
prop2 x
prop2 y
Если вместо этого мы используем POST(используется по умолчанию, когда указан params), происходят аналогияные вещи, за исключением того, что пары имя/значение отправляются как тело POST-запроса.
Для отправки JSON на сервер, нам необходимо использовать Ext.encode() для конвертирования наших данных в строку JSON. Ext.Ajax.request() ожидает url-кодированную строку, поэтому вы можете или самостоятельно кодировать ее, используя encodeURIComponent(), или еще лучше превратите вашу JSON-строку в простой объект и получите кодирование, сделанное за вас Ext.Ajax.request():
var req = Ext.Ajax.request({ url: "/ws/search.pl", params: {json: Ext.encode(obj)}, disableCaching: false })
Как и раньше, сервер увидит:
{"prop1":"a0~`!@#$%^&*()-_+={}[]|\\:;\"',.?/","prop2":["x","y"],"prop3":{"nestedProp1":"abc","nestedProp2":456}}
Которую вы затем можете декодировать для доступа к данным.