Actionscript3 to JavaScript communication: best practices - javascript

On a more abstract level then a previous question, in my experience there are 3 ways to call a javascript function on an html page from an embedded .swf using AS3: ExternalInterface, fscommand, and navigateToURL.
Let's compare and contrast these methods (and maybe others I haven't listed) and talk about the pros and cons of each - right now, ExternalInterface seems like the way to go in terms of flexibility, but is it right for all situations? Are there concrete benefits in terms of execution speed or anything like that? I'm curious - what do we think?

ExternalInferface was created to make communication between JS and Flash easier, so it doens't really make sense to use anything else. Common practice is to check if its available first by evaluating the value of the ExternalInterface.available property before making a call to some JS. This property tells you if the SWF in which you want to call some JS from is inside a container that offers an external interface. In otherwords, if using ExternalInterface will work. If its not available then just use flash.net.sendToUrl. Never use fscommand() as it uses VBScript and can cause conflicts with other VBScript on a page. Additionally, you can only send one argument string with fscommand and have to split it on the JS side.

It all depends on if you want the communication to be synchronous or not as ExternaInterface can return data as where navigatoToURL and fscommand are asynchronous and can only call a javascript function; they cannot return values or a response.
From live docs in relation to External Interface:
From ActionScript, you can do the following on the HTML page:
Call any JavaScript function.
Pass any number of arguments, with any names.
Pass various data types (Boolean, Number, String, and so on).
Receive a return value from the JavaScript function.
From JavaScript on the HTML page, you can:
Call an ActionScript function.
Pass arguments using standard function call notation.
Return a value to the JavaScript function.
The flash.external.ExternalInterface class is a direct replacement for the flash.system.fscommand class.
So using ExternalInterface is the preferred method or communication between flash and a Javascript function, though if the call is merely Asynchronous it is ok to use flash.net.navigateToURL.

ExternalInterface
You can get the return value from JS-AS and AS-JS calls
Encodes your arguments (call with arrays, objects, etc. No need to encode them)
Cross browser
Flawed when you send HTML or JSON (special encoding), it breaks internally
getURL
You can only call JS, you not get the return value and you need to encode your data
Was nice than deprecated and in Flash 10 it's removed
It is really removed, so don't use it ;)
fscommand
Come on, ExternalInterface is the solution (for 2008).

Related

Getting user agent value. Server side vs Client side?

I need to pass user agent value into front end.
I can get this value using $_SERVER['HTTP_USER_AGENT'] and write it into front end.
(Actually I will be using Mage::helper('core/http')->getHttpUserAgent(), but I think it's just a magento helper to call above mentioned function.)
Or I can use get navigator.userAgent with js on client side.
Which better and why? My primary concern is speed.
p.s. I understand that UA can be easily manipulated. We are not basing any serious functionality on the value, it's used as a secondary parameter.
I would personally use navigator.userAgent. Mainly, because passing values from PHP to JavaScript is pretty ugly in my opinion. Also, the value will be exactly the same for both. Even if someone decides to edit their useragent.
I think simplicity takes the cake here.
Performance will depend on the purpose. If you need this inside php, then use the server variable with helper getter you mentioned above. For js use navigator object.
In general both navigator.userAgent and HTTP_USER_AGENT are variables of Request Header and are both already present in memory (of server or users browser in case of js). So no measurable performance difference is possible.

Best practise for context mode at runtime in JS

I have a web application based on apache. php, js and jquery. All works fine.
On the client side there is a small library in JS/jquery, offering some generic list handling methods. In the past I used callbacks to handle those few issues where those methods had to behave slightly different. That way I can reuse methods like list handling, dialog handling and stuff for different part of the application. However recently the number of callbacks I had to hand through when stepping into the library grew and I am trying a redesign:
Instead of specifying all callbacks as function arguments I created a central catalog object in the library. Each module of the application registers its own variant of callbacks into that catalog upon initialization. At runtime the methods lookup the required callbacks in that catalog instead of expecting it specified in their list of arguments. This cleans up things quite a lot.
However I have one thing I still cannot get rid of: I require a single argument (I call it context, mode might be another term) that is used by the methods to lookup the required callback in the catalog. This context has to be handed through to all methods. Certainly better than all sorts of different callbacks being specified everywhere, but I wonder if I can get rid of that last one to.
But where do I specify that context, if not as method argument ? I am pretty new to JS and jquery, so I failed to find an approach for this. Apparently I don't want to use global vars, and to be frank I doubt that I can simply store a context in a single variable anyway, since because of all the event handlers and external influences methods might be called in different contexts at the same time, or at least interleaving. So I guess I need something closer to a function stack. Maybe I can simply push a context object to the stack and read that from within the layers of the library that need to know ? The object would be removed when I leave the library again. Certainly other approaches exist too.
Here are so many experienced coders how certainly can give a newbie like a short hint, a starting point that leads to an idea, how to implement this. How is such thing 'usually' done ?
I tried round a while, exploring the arguments.callee.caller hierarchy. I thought maybe I could set a prototype member inside a calling function, then, when execution steps further down I could simply traverse the call stack upwards until I find a caller holding such property and use that value as context.
However I also saw the ongoing discussions that reveal two things: 1.) arguments.callee appears to be depreciated and 2.) it appears to be really expensive. So that is a no go.
I also read about the Function.caller alternative (which appears not to be depreciated and much more efficient, however until now I failed to explore that trail...
As written currently passing the context/mode down simply works by specifying an additional argument in the function calls. It carries a unique string that is used as a key when consulting the catalog. So something like this (not copied, but written as primitive example):
<!-- callbacks -->
callback_inner_task_base:function(arg1,arg2){
// do something with args
}
callback_inner_task_spec:function(arg1,arg2){
// do something with args
}
<!-- catalog -->
Catalog.Callback:function(context,slot){
// some plausibility checks...
return Catalog[context][slot];
}
Catalog.base.slot=callback_inner_task_base;
Catalog.spec.slot=callback_inner_task_spec;
<!-- callee -->
do_something:function(arg1,arg2,context){
...
// callback as taken from the catalog
Catalog.Callback(callback,'inner_task')(arg1,arg2);
...
}
<!-- caller -->
init:function(...){
...
do_something('thing-1',thing-2','base');
do_something('thing-1',thing-2','spec');
...
}
But where do I specify that context, if not as method argument ?
Use a function property, such as Catalog.Callback.context
Use a monad

javascript - how to execute a simple GET webrequest?

How can I execute a simple webrequest in javascript.
Such as
var str = *whatever_comes_back_from*("search.php?term=hello");
This is usually handed via XMLHttpRequest, usually abstracted via a library that irons out the differences between browsers (bigger libraries that do lots of other stuff include YUI and jQuery).
You could use jQuery, or another javascript library, but instead of thinking of populating the variable then continueing with the script in a linear way, you should think in terms of a callback once the value is retrieved, because it can take a variable amount of time to retrieve the data.
This event based architecture is a feature of javascript that is rare in other programming languages.
$.get('search.php?term=hello', function(data){
alert(data)
});

Should ajax calls go through as few as possible entry points to an application or many specific methods

I'm building a web app with a lot of ajax calls to be made.
Should I be trying to keep a small number of methods, and just pass in information about what type of request it is, and then switch based on that type inside the method
or
Many smaller methods, so don't have to pass in type, but more code to write setting up each method.
Currently I'm passing type from the id of the element being interacted with in the html, and then this tells me what I'm trying to do
row-action-data-id (I then split this in the functions, to work out what needs doing)
Are there any best practices for patterns like this?
its a judgement call. you always want to refactor out any duplicate code as much as possible but its important that your code is readable and maintainable.

Is getting JSON data with jQuery safe?

JSON allows you to retrieve data in multiple formats from an AJAX call. For example:
$.get(sourceUrl, data, callBack, 'json');
could be used to get and parse JSON code from sourceUrl.
JSON is the simply JavaScript code used to describe data. This could be evaled by a JavaScript interpreter to get a data structure back.
It's generally a bad idea to evaluate code from remote sources. I know the JSON spec doesn't specifically allow for function declarations, but there's no reason you couldn't include one in code and have an unsafe and naive consumer compile/execute the code.
How does jQuery handle the parsing? Does it evaluate this code? What safeguards are in place to stop someone from hacking sourceUrl and distributing malicious code?
The last time I looked (late 2008) the JQuery functions get() getJSON() etc internally eval the JSon string and so are exposed to the same security issue as eval.
Therefore it is a very good idea to use a parsing function that validates the JSON string to ensure it contains no dodgy non-JSON javascript code, before using eval() in any form.
You can find such a function at https://github.com/douglascrockford/JSON-js/blob/master/json2.js.
See JSON and Broswer Security for a good discussion of this area.
In summary, using JQuery's JSON functions without parsing the input JSON (using the above linked function or similar) is not 100% safe.
NB: If this sort of parsing is still missing from getJSON (might have recently been added) it is even more important to understand this risk due to the cross domain capability, from the JQuery reference docs:
As of jQuery 1.2, you can load JSON
data located on another domain if you
specify a JSONP callback, which can be
done like so: "myurl?callback=?".
jQuery automatically replaces the ?
with the correct method name to call,
calling your specified callback.
$.getJSON() is used to execute (rather than using eval) javascript code from remote sources (using the JSONP idiom if a callback is specified). When using this method, it is totally up to you to trust the source, because they will have control to your entire page (they can even be sending cookies around).
From Douglas Crockford site about The Script Tag Hack (jsonp):
So the script can access and use
its cookies. It can access the
originating server using the user's
authorization. It can inspect the DOM
and the JavaScript global object, and
send any information it finds anywhere
in the world. The Script Tag Hack is
not secure and should be avoided.
Both IE 8 and Firefox 3.1 will have native JSON support, which will provide a safe alternative to eval(). I would expect other browsers to follow suit. I would also expect jQuery to change its implementation to use these native methods.
All browsers I know of disable cross-site requests through Ajax. That is, if your page sits on my.example.com, you can't load anything using Ajax unless its URL is also at my.example.com.
This actually can be something of a nuisance, and there are ways for an attacker to inject source in other ways, but ostensibly this restriction is in place to address exactly the concern you mention.

Categories

Resources