Jeez, in the win.error function you have to set done to true of course, or
else you would get multiple error reports.

2009/3/15 Julian Aubourg <[email protected]>

> Regarding security issues it's a "somehow yes but" answer. The technique
> limits the risks in that malicious code would have to be aware it's being
> run from an iframe. However, since the iframe is created by the main window,
> there is no cross-domain barrier and malicious code could access the main
> window using the "parent" and "top" variables.
> I remember I tried to set "parent" to undefined at one point. Depending on
> the situation, I got a javascript error (the one that says you cannot change
> the field of the object) or no error but "parent" was still accessible from
> the iframe. Though I must say I was experimenting like crazy at that time
> and I didn't get the iframe lifecycle right (especially the fact you need to
> open the document before adding fields to the window object or else
> sometimes -- notice the sometimes -- the variable were not actually
> accessible from within the iframe).
>
> Now, for the approach, it's a very very silly catch-all trick:
>
> var iframe = $("<iframe />");
> $("head").append(iframe);
>
> var win = /* plumbery code */; // the iframe window
> var doc = /* plumbery code */; // the iframe document
>
> var done = false;
>
> doc.open();
>
> win.callback = function(json) {
>   done = true;
>   // cleanup
>   // call the success callback with json
> };
>
> win.error = function() {
>   if (done) return; // already treated
>   // cleanup
>   // call the error callback
> };
>
> doc.write(SEE_CODE_BELOW);
> doc.close();
>
> Where SEE_CODE_BELOW is something like:
>
> <html>
>  <head>
>   <script type="text/javascript"
> src="YOUR_SCRIPT?callbackParameter=callback"></script>
>   <script type="text/javascript">error()</script>
>  </head>
>  <body onload="error()" onerror="error()">
>  </body
> </html>
>
> This is the technique I came up with to catch errors on every browser I
> tested the code on. The rest is mostly plumbery code with some
> setTimeout(xxx,1) to control the execution flow (saved me a nasty crash in
> Safari who doesn't appreciate when you .remove() an iframe from code the
> iframe is the callee of).
>
> I know the one letter variable policy is stupid, I was just terribly
> anxious about size. I don't think this kind of plugin should be as large as
> 5kB like my previous getJSON one. I tried to find an obfuscator that was
> solid but couldn't. I'd love to be able to have a clean code and then a very
> compact minified output.
>
> But I agree I went a little berserk here. OK, I went crazy-berserk :P
>
> 2009/3/15 Jörn Zaefferer <[email protected]>
>
>
>> Could the jsonp-over-iframe approach also remove some of the security
>> concerns associated with jsonp? That is, what happens when a jsonp
>> resource is replaced with a malicious script? Is the script restricted
>> to the iframe?
>>
>> Having proper error handling for jsonp sounds very promising.
>>
>> One thing I noticed after looking at the source code: Using
>> one-character variable names is something to be avoided - makes the
>> code really hard to read. Couldn't quite figure out how you implement
>> the error handling...
>>
>> Jörn
>>
>> On Sat, Mar 14, 2009 at 6:54 PM, Julian Aubourg
>> <[email protected]> wrote:
>> > I've tested it in Firefox 3.x, Chrome 1.x, IE7, Opera 9.x, Safari 3.x.
>> All
>> > windows versions. It uses an iframe instead of a simple script tag (wich
>> > brings a separate window context, hence the added flexibility in
>> callback
>> > naming and the possibility to detect faulty requests). I'm pretty
>> confident
>> > it's generic enough to work in all browsers supported by jQuery (maybe
>> with
>> > some tweaks here and there because declaring variables in the iframe
>> > window's context must be done at the proper stage in the iframe's
>> lifecycle
>> > -- I managed to find a common ground for the browsers I tested the
>> plugin in
>> > but let me tell you I battled to find it). I know I could have made
>> things
>> > simpler by exposing callback functions as fields of an object in the
>> main
>> > window's context ($.jsonp.callbacks for instance) but then I would have
>> lost
>> > the benefit of the same callback name for every call.
>> > "Being able to specify a fixed jsonp callback function seems useful too
>> and
>> > probably not hard to add."
>> > With a script tag in the main window's head, it's almost impossible
>> unless
>> > you have a global data structure to reroute responses and a callback
>> > function code generator or expect the user to filter what response
>> > corresponds to what request in his own callbacks. Keep in mind you may
>> have
>> > several requests running with the same callback name at once and you
>> don't
>> > know in which order they'll complete. It seems strange to me you seem to
>> > find this callback naming thing so secondary. I can assure you that the
>> > features the plugin provides in that department are as valuable as
>> getting
>> > an error callback properly notified.
>> > Anyway, the source is MIT and for good reason ;) so don't hesitate to
>> > pillage it as you see fit. All variables are one-letter for size purpose
>> but
>> > it 's heavily commented and should be easy to follow.
>> > Now on the topic of having $.ajax() being a catch-all method for every
>> > protocol on the planet, I'm not sure I buy it. I was browsing through
>> > $.ajax() source code and I was quite puzzled at the number of
>> conditionals
>> > and tricks packed in a single function. I was almost surprised not to
>> see an
>> > image preloading subcase in there ;)
>> > I mean, JSONP is not AJAX, unfortunately mainly due to technical
>> > differencies. For instance:
>> > - the dataFilter callback will never receive text simply because the
>> browser
>> > never has access to it in the first place, so you end up passing the
>> > resulting JSON object to it,
>> > - you cannot pass an xhr object to the callbacks because there's none
>> hence
>> > my use in $.jsonp() of an object containing the request's options and an
>> > abort method. Imagine the clarity of the documentation regarding said
>> > callbacks if you had to implement that into $.ajax() (not to mention how
>> > bloated the code would get)
>> > - you never, ever have access to HTTP headers (which would be incredibly
>> > nice btw)
>> > From a practical point of view, I guess most people will use $.getJSON
>> so
>> > that they don't have to deal with the intricaties of $.ajax() options
>> > setting. That's in this spirit that I created $.json() (which has far
>> less
>> > options). It seemed the easier, safer and cleaner way to go.
>> > As a side note, I'm not sure I like the idea of setting defaults through
>> > $.ajaxSetup() that will be applied to XML, text, JSON, JSONP and
>> whatever
>> > new data format / protocol either. Don't get me wrong, I have a
>> $.json.setup
>> > method myself and I know there's a need but it seems to "all or nothing"
>> to
>> > me. I've just finished an add-on to $.jsonp() that will allow to make
>> > "prepared" requests (a bit like SQL prepared statements). The idea is
>> > basically to create pre-made functions that actually call $.jsonp() but
>> with
>> > default options (and a url templating engine and a nice arguments to
>> request
>> > data mapper). Interestingly, the technique can be applied to $.ajax()
>> and
>> > the add-on installs the hook for it too. All it needs right now is
>> > documentation (I hate to release without at least an API doc and some
>> > examples). Hell, here is an example taken from my test file of how it
>> works,
>> > I can't resist:
>> > // Creating the prepared request
>> > var getYouTubeUser = $.jsonp.prepared(
>> >    // url template
>> >    
>> > "http://gdata.youtube.com/feeds/api/users/{user}?callback=<http://gdata.youtube.com/feeds/api/users/%7Buser%7D?callback=>
>> ?",
>> >    // generated function parameters
>> >    // undefined: no default value, optional parameter
>> >    // null: no default value, mandatory parameter
>> >    {
>> >       "user": null,
>> >    },
>> >    // default parameters for the request
>> >    {
>> >       "data": {
>> >          "alt": "json-in-script"
>> >       },
>> >       "dataFilter": dataFilter
>> >    }
>> > );
>> > // Using the function
>> > getYouTubeUser("julianaubourg")({
>> >    "success": function(json) {
>> >       // success code
>> >    },
>> >    "error": function(d,msg) {
>> >       // error code
>> >    }
>> > });
>> >
>> > In conclusion, well, I think json support in $.ajax() as of today is
>> enough
>> > for what most people will attempt with it (that is pretty simple and
>> borded
>> > requests). I really think $.jsonp is more oriented toward advanced uses
>> (I
>> > made it because I'm working on a heavily service-consuming website at
>> the
>> > moment and thought some people would need something more advanced like I
>> > did).
>> > Oh yeah, and from a performance point of view, using iframes instead of
>> > script tags is much more time consuming. Empirical tests I made showed
>> that
>> > sending a jsonp request to a local webserver (static text) using
>> $.jsonp()
>> > is about 2x to 10x slower than the $.ajax() method (Safari being the
>> fastest
>> > and Firefox the slowest). I blame it on the insane chrome activity that
>> is
>> > performed by most browsers when you have an iframe loading. Of course,
>> it's
>> > still a fraction of the time a normal request over the network will take
>> but
>> > it still has to be taken in consideration.
>> > Regards,
>> > -- Julian
>> > 2009/3/14 Dave Methvin <[email protected]>
>> >>
>> >> > To summarize, $.jsonp() is ... an entirely new function which
>> provides
>> >> > the same options as $.ajax() does (as long as said options are
>> relevant
>> >> > to a jsonp request).
>> >>
>> >> Yeah, that's what $.ajax is trying to do with jsonp as well. At the
>> >> moment I think there are some issues with jsonp through $.ajax, a
>> >> combination of documentation problems and missing features that could
>> >> be implemented for consistency with other $.ajax requests.
>> >>
>> >> On the error callback, does that solution work in all browsers? If so,
>> >> it sounds like $.ajax should implement it for jsonp. Being able to
>> >> specify a fixed jsonp callback function seems useful too and probably
>> >> not hard to add.
>> >>
>> >
>> >
>> > >
>> >
>>
>> >>
>>
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"jQuery Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/jquery-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to