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 -~----------~----~----~----~------~----~------~--~---
