1Catalyst::View::JSON(3)User Contributed Perl DocumentatioCnatalyst::View::JSON(3)
2
3
4

NAME

6       Catalyst::View::JSON - JSON view for your data
7

SYNOPSIS

9         # lib/MyApp/View/JSON.pm
10         package MyApp::View::JSON;
11         use base qw( Catalyst::View::JSON );
12         1;
13
14         # configure in lib/MyApp.pm
15         MyApp->config({
16             ...
17             'View::JSON' => {
18                 allow_callback  => 1,    # defaults to 0
19                 callback_param  => 'cb', # defaults to 'callback'
20                 expose_stash    => [ qw(foo bar) ], # defaults to everything
21             },
22         });
23
24         sub hello : Local {
25             my($self, $c) = @_;
26             $c->stash->{message} = 'Hello World!';
27             $c->forward('MyApp::View::JSON');
28         }
29

DESCRIPTION

31       Catalyst::View::JSON is a Catalyst View handler that returns stash data
32       in JSON format.
33

CONFIG VARIABLES

35       allow_callback
36           Flag to allow callbacks by adding "callback=function". Defaults to
37           0 (doesn't allow callbacks). See "CALLBACKS" for details.
38
39       callback_param
40           Name of URI parameter to specify JSON callback function name.
41           Defaults to "callback". Only effective when "allow_callback" is
42           turned on.
43
44       expose_stash
45           Scalar, List or regular expression object, to specify which stash
46           keys are exposed as a JSON response. Defaults to everything. Exam‐
47           ples configuration:
48
49             # use 'json_data' value as a data to return
50             expose_stash => 'json_data',
51
52             # only exposes keys 'foo' and 'bar'
53             expose_stash => [ qw( foo bar ) ],
54
55             # only exposes keys that matches with /^json_/
56             expose_stash => qr/^json_/,
57
58           Suppose you have data structure of the following.
59
60             $c->stash->{foo} = [ 1, 2 ];
61             $c->stash->{bar} = [ 3, 4 ];
62
63           By default, this view will return:
64
65             {"foo":[1,2],"bar":2}
66
67           When you set "expose_stash => [ 'foo' ]", it'll return
68
69             {"foo":[1,2]}
70
71           and in the case of "expose_stash => 'foo'", it'll just return
72
73             [1,2]
74
75           instead of the whole object (hashref in perl). This option will be
76           useful when you share the method with different views (e.g. TT) and
77           don't want to expose non-irrelevant stash variables as in JSON.
78
79       json_driver
80             json_driver: JSON::Syck
81
82           By default this plugin uses JSON to encode the object, but you can
83           switch to the other drivers like JSON::Syck, whichever JSON::Any
84           supports.
85
86       no_x_json_header
87             no_x_json_header: 1
88
89           By default this plugin sets X-JSON header if the requested client
90           is a Prototype.js with X-JSON support. By setting 1, you can opt-
91           out this behavior so that you can do eval() by your own. Defaults
92           to 0.
93

OVERRIDING JSON ENCODER

95       By default it uses JSON::Any to serialize perl data strucuture into
96       JSON data format. If you want to avoid this and encode with your own
97       encoder (like passing options to JSON::XS etc.), you can implement
98       "encode_json" method in your View class.
99
100         package MyApp::View::JSON;
101         use base qw( Catalyst::View::JSON );
102
103         use JSON::XS;
104
105         sub encode_json {
106             my($self, $c, $data) = @_;
107             my $encoder = JSON::XS->new->ascii->pretty->allow_nonref;
108             $encoder->encode($data);
109         }
110
111         1;
112

ENCODINGS

114       Due to the browser gotchas like those of Safari and Opera, sometimes
115       you have to specify a valid charset value in the response's Content-
116       Type header, e.g. "text/javascript; charset=utf-8".
117
118       Catalyst::View::JSON comes with the configuration variable "encoding"
119       which defaults to utf-8. You can change it via "YourApp->config" or
120       even runtime, using "component".
121
122         $c->component('View::JSON')->encoding('euc-jp');
123
124       This assumes you set your stash data in raw euc-jp bytes, or Unicode
125       flagged variable. In case of Unicode flagged variable, Cata‐
126       lyst::View::JSON automatically encodes the data into your "encoding"
127       value (euc-jp in this case) before emitting the data to the browser.
128
129       Another option would be to use JavaScript-UCS as an encoding (and pass
130       Unicode flagged string to the stash). That way all non-ASCII characters
131       in the output JSON will be automatically encoded to JavaScript Unicode
132       encoding like \uXXXX. You have to install Encode::JavaScript::UCS to
133       use the encoding.
134

CALLBACKS

136       By default it returns raw JSON data so your JavaScript app can deal
137       with using XMLHttpRequest calls. Adding callbacks (JSONP) to the API
138       gives more flexibility to the end users of the API: overcome the cross-
139       domain restrictions of XMLHttpRequest. It can be done by appending
140       script node with dynamic DOM manipulation, and associate callback han‐
141       dler to the returned data.
142
143       For example, suppose you have the following code.
144
145         sub end : Private {
146             my($self, $c) = @_;
147             if ($c->req->param('output') eq 'json') {
148                 $c->forward('MyApp::View::JSON');
149             } else {
150                 ...
151             }
152         }
153
154       "/foo/bar?output=json" will just return the data set in "$c->stash" as
155       JSON format, like:
156
157         { result: "foo", message: "Hello" }
158
159       but "/foo/bar?output=json&callback=handle_result" will give you:
160
161         handle_result({ result: "foo", message: "Hello" });
162
163       and you can write a custom "handle_result" function to handle the
164       returned data asynchronously.
165
166       The valid characters you can use in the callback function are
167
168         [a-zA-Z0-9\.\_\[\]]
169
170       but you can customize the behaviour by overriding the "validate_call‐
171       back_param" method in your View::JSON class.
172
173       See <http://developer.yahoo.net/common/json.html> and <http://ajax
174       ian.com/archives/jsonp-json-with-padding> for more about JSONP.
175

INTEROPERABILITY

177       JSON use is still developing and has not been standardized. This sec‐
178       tion provides some notes on various libraries.
179
180       Dojo Toolkit: Setting dojo.io.bind's mimetype to 'text/json' in the
181       JavaScript request will instruct dojo.io.bind to expect JSON data in
182       the response body and auto-eval it. Dojo ignores the server response
183       Content-Type. This works transparently with Catalyst::View::JSON.
184
185       Prototype.js: prototype.js will auto-eval JSON data that is returned in
186       the custom X-JSON header. The reason given for this is to allow a sepa‐
187       rate HTML fragment in the response body, however this of limited use
188       because IE 6 has a max header length that will cause the JSON evalua‐
189       tion to silently fail when reached. The recommened approach is to use
190       Catalyst::View::JSON which will JSON format all the response data and
191       return it in the response body.
192
193       In at least prototype 1.5.0 rc0 and above, prototype.js will send the
194       X-Prototype-Version header. If this is encountered, a JavaScript eval
195       will be returned in the X-JSON resonse header to automatically eval the
196       response body, unless you set no_x_json_header to 1. If your version of
197       prototype does not send this header, you can manually eval the response
198       body using the following JavaScript:
199
200         evalJSON: function(request) {
201           try {
202             return eval('(' + request.responseText + ')');
203           } catch (e) {}
204         }
205         // elsewhere
206         var json = this.evalJSON(request);
207

SECURITY CONSIDERATION

209       Catalyst::View::JSON makes the data available as a (sort of) JavaScript
210       to the client, so you might want to be careful about the security of
211       your data.
212
213       Use callbacks only for public data
214
215       When you enable callbacks (JSONP) by setting "allow_callbacks", all
216       your JSON data will be available cross-site. This means embedding pri‐
217       vate data of logged-in user to JSON is considered bad.
218
219         # MyApp.yaml
220         View::JSON:
221           allow_callbacks: 1
222
223         sub foo : Local {
224             my($self, $c) = @_;
225             $c->stash->{address} = $c->user->street_address; # BAD
226             $c->forward('View::JSON');
227         }
228
229       If you want to enable callbacks in a controller (for public API) and
230       disable in another, you need to create two different View classes, like
231       MyApp::View::JSON and MyApp::View::JSONP, because "allow_callbacks" is
232       a static configuration of the View::JSON class.
233
234       See <http://ajaxian.com/archives/gmail-csrf-security-flaw> for more.
235
236       Avoid valid cross-site JSON requests
237
238       Even if you disable the callbacks, the nature of JavaScript still has a
239       possiblity to access private JSON data cross-site, by overriding Array
240       constructor "[]".
241
242         # MyApp.yaml
243         View::JSON:
244           expose_stash: json
245
246         sub foo : Local {
247             my($self, $c) = @_;
248             $c->stash->{json} = [ $c->user->street_address ]; # BAD
249             $c->forward('View::JSON');
250         }
251
252       When you return logged-in user's private data to the response JSON, you
253       might want to disable GET requests (because script tag invokes GET
254       requests), or include a random digest string and validate it.
255
256       See <http://jeremiahgross
257       man.blogspot.com/2006/01/advanced-web-attack-techniques-using.html> for
258       more.
259

AUTHOR

261       Tatsuhiko Miyagawa <miyagawa@bulknews.net>
262

LICENSE

264       This library is free software; you can redistribute it and/or modify it
265       under the same terms as Perl itself.
266

CONTRIBUTORS

268       Following people has been contributing patches, bug reports and sugges‐
269       tions for the improvement of Catalyst::View::JSON.
270
271       John Wang kazeburo Daisuke Murase Jun Kuriyama
272

SEE ALSO

274       Catalyst, JSON, Encode::JavaScript::UCS
275
276       <http://www.prototypejs.org/learn/json>
277       <http://docs.jquery.com/Ajax/jQuery.getJSON> <http://manual.dojo
278       toolkit.org/json.html> <http://developer.yahoo.com/yui/json/>
279
280
281
282perl v5.8.8                       2008-04-12           Catalyst::View::JSON(3)
Impressum