ActionScript3 (AS3) External Interface call to javascript/jquery function not working - javascript

I am working on a project that is intended to track users using Local Shared Objects. The user first visits page A, which has an embedded .swf that plants a Local Shared Object. I know it works by testing it my own flash cookies.
Upon visiting page B, another embedded .swf will attempt to retrieve the flash cookie and call an AJAX function if the cookie is present. Page B is what I am having trouble with. On this webpage is embedded a .swf object, along with an AJAX function. The following code is the HTML for page B. It includes the AJAX script, along with an embedded .swf.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
function databaseAndemail(){
$.get('http://www.mywebsite.com/databaseAndemail.php');
}
</script>
</head>
<body>
<object width="1" height="1">
<param name="CheckLSO" value="http://www.mywebsite.com/CheckLSO.swf">
<embed src="http://www.mywebsite.com/CheckLSO.swf" width="1" height="1">
</embed>
</object>
</body>
The problem is not with the AJAX function, nor the PHP script, because I know that works. The problem may lie within the .swf script that is meant to check the LSO. This is the AS3 script called CheckLSO.swf:
public function Main():void
{
//Check for a LSO
var myLocalData:SharedObject = SharedObject.getLocal("myData");
if (myLocalData.data.uname != null){ //LSO exists, so call AJAX function to update database and send email.
if (ExternalInterface.available){
ExternalInterface.call("databaseAndemail");
}
};
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
I'll include the AS3 script that sets the cookies here for your information (again, I've tested this one and it works):
public function Main():void
{
// Create a new SharedObject
var myLocalData:SharedObject = SharedObject.getLocal("myData");
// Save data to the SharedObject
myLocalData.data.uname = "ERE";
myLocalData.flush();
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
To sum it up, I think for some reason the Javascript function is not being called by External Interface. I know the cookie is set, I know the AJAX works, and I know the PHP script works (I haven't included the PHP, it seems like it would be outside the scope of this question). Both .swf scripts are debugged. I use FlashDevelop with Flex 4. These are really simple scripts, so I can't think of anything else that might be going wrong. Any ideas??

Might be the script access setting. On the embed, try including the param allowscriptaccess: "always". External Interface calls will fail without it.
<object width="1" height="1">
<param name="CheckLSO" value="http://www.mywebsite.com/CheckLSO.swf">
<param name="allowscriptaccess" value="always">
<embed src="http://www.mywebsite.com/CheckLSO.swf" width="1" height="1"></embed>
</object>
Better yet, use swfObject 2 to embed your swf.
SwfObject

Related

calling actionscript 3 function from javascript with addCallback not working

I have a requirement in a project which has to call an actionscript 3 function from javascript. I read many answers from stackoverflow and adobe and have created a simple test application. In that, I have used ExternalInterface.addCallback to register both the functions and I've also included the security permissions in both actionscript and in html.
Action Script 3 Embedded code
I did not use an external .as file instead i used the action panel to create the code.
import fl.controls.Button
import flash.events.MouseEvent;
flash.system.Security.allowDomain("*")
var butt:Button = new Button();
addChild(butt);
butt.label = "hello";
butt.toggle = true;
butt.move(50, 50);
butt.height = 100;
butt.addEventListener(MouseEvent.CLICK, clickhandle);
function clickhandle(e:MouseEvent)
{
if(butt.height == 100)
butt.height = 200;
else butt.height = 100;
}
ExternalInterface.addCallback("callas", clickhandle);
The test app will display a ac3 button. Upon clicking that button it will toggle the expanding and collapsing of its height through a click handler 'clickhandle'. This is the function i am intended to call from javascript.
HTML Code
<html>
<head>
<script>
function callas() {
var hehe = document.getElementById('cvpanel');
console.log(hehe);
hehe.clickhandle();
}
</script>
</head>
<body>
<p>Test</p>
<object id='cvpanel' name='cvpanel' width="425" height="350" type="application/x-shockwave-flash" data="one.swf">
<param value="one.swf" name="movie">
<param name="allowscriptaccess" value="always"/>
<p>You need Flash to see it.</p>
</object>
</body>
</html>
The application runs under http://localhost through apache and all the files needed are in the same folder. I could run the application and could see the buttons appearing. By clicking it they toggle in height as expected.
When i call the function callas from browser console i get the error in console as
"TypeError: hehe.clickhandle is not a function"
in firefox and similar in Internet Explorer.
Is there anything missing?
In flash you're exposing clickhandle as callas
ExternalInterface.addCallback("callas", clickhandle);
so you're supposed to call callas() from javascript
var hehe = document.getElementById('cvpanel');
hehe.callas();

HTML5 Video link not working in Chrome

I have the following code for viewing my webcam directly via a publicly accessible link.
<!DOCTYPE html>
<html>
<head>
<title>webRTC Test</title>
</head>
<script type = "text/javascript">
function init()
{
if(navigator.webkitGetUserMedia)
{
navigator.webkitGetUserMedia({video:true}, onSuccess, onFail);
}
else
{
alert('webRTC not available');
}
}
function onSuccess(stream)
{
document.getElementById('camFeed').src = webkitURL.createObjectURL(stream);
var src = document.getElementById('camFeed').getAttribute('src');
document.getElementById('streamLink').href = src;
}
function onFail()
{
alert('could not connect stream');
}
</script>
<body onload = "init();" style="background-color:#ababab;">
<div style="width:352px; height:625px; margin:0 auto; background-color:#fff;">
<div>
<video id ="camFeed" width="320" height="240" autoplay>
</video>
</div>
<div>
<canvas id="photo" width="320" height="240">
</canvas>
</div>
<div style="margin: 0 auto; width:82px;">
<a id="streamLink">Visit Stream</a>
</div>
</div>
</div>
</body>
</html>
The link generated in the anchor tag is something like:
blob:http%3A//sitename.com/7989e43a-334r-4319-b9c5-9dfu00b00cd0
And upon visiting chrome tells me "Oops! This link appears to be broken."
Help appreciated!
The File API spec defines URL.createObjectURL. There are a couple of sections that make what you're trying to do impossible in a browser that follows the spec.
Section 11.5 says:
The origin of a Blob URI must be the origin of the script that called URL.createObjectURL. Blob URIs must only be valid within this origin.
In other words, the URIs returned by createObjectURL can only be used within the context of the website that created them (see RFC6454: The Web Origin Concept for a more precise definition of what the HTML specs mean by “origin”). You can't visit a URL returned by createObjectURL directly.
Section 11.6 says:
This specification adds an additional unloading document cleanup step: user agents must revoke any Blob URIs created with URL.createObjectURL from within that document.
This means that even if you could visit the URL directly, as soon you you leave the page that called createObjectURL the URL that was created ceases to exist.
You must ensure that you’re using/testing your code at HTTP or HTTPs protocols --- because URL.createObjectURL has some issues at file:// protocol --- and it can’t be able to generate right BLOB for your video while using file:// ---- !!!
Your code won't work on localhost or your machine alone.
All you need is, upload this HTML document on the Net(just in case you are wondering on how to get Hosting for yourself, then try checkout Dropbox, you can upload your HTML page publicly and get access via Public Link for free or try some other product or simply get hosting for yourself). As you can see that this example http://www.html5rocks.com/en/tutorials/getusermedia/intro/ works perfectly in chrome, though the code that it is utilising is the same as yours. I hope this solution is of some help to your and others searching for an answer to this bug.
Also, you can then use an iframe to get access to the video element to perform operations on it.

Setting data attribute for object element in html

i have an object element in my html body to show an Active reports which exports to a .pdf file. I need to use javascript to automatically print the pdf out to the client's default printer and then save the pdf to the server:
<script language="javascript" type="text/javascript">
// <!CDATA[
function PrintPDF() {
pdf.click();
pdf.setActive();
pdf.focus();
pdf.PrintAll();
}
// ]]>
....
<body onload="return PrintPDF();">
<form id="form1" runat="server">
<object id="pdfDoc" type="application/pdf" width="100%" height="100%" data="test.aspx?PrintReport=yes&SavePDF=yes"/>
</form>
</body>
With the data hard-code in the object tag, everything run without a problem.
The problem now is that I need to pass querystring to this page dynamically. I tried to set the attribute data in the javsacript to pass the querystring. The querystring value passed successfully, but the data attribute does not seem to be set. I get a blank page.
pdf.setAttribute("data","test.aspx?PrintReport=yes&SavePDF=yes&AccNum="+AccNum);
Does anyone have a clue how I can set the data attribute dynamically to pass in querystring?
Thanks,
var pdfObj = document.getElementById('pdfDoc');
pdfObj.data="test.aspx?PrintReport=yes&SavePDF=yes&AccNum="+AccNum;
As far as the data attribute you're doing everything fine. Here are some examples:
http://jsfiddle.net/3SxRu/
I think your problem might be more to do with the order of execution. What does your actual code look like? Are you writing over the body onLoad function or something?
Also, I assume using the data attribute is a requirement. HTML5 defines data-*. This attribute isn't really valid. Again, maybe your system requires it.
I suspect that things are happening out of order. Try waiting until the onload event of the window before adding the embed.
Also, I suggest using a script like PDFObject to handle the embedding since it is a reliable way to embed PDF across all the various browsers out there. For example you might have something like the following:
<html>
<head>
<title>PDFObject example</title>
<script type="text/javascript" src="pdfobject.js"></script>
<script type="text/javascript">
window.onload = function (){
// First build the link to the PDF raw data ("bits")
// getQueryStrings assumes something like http://stackoverflow.com/questions/2907482/how-to-get-the-query-string-by-javascript
var queryStrings = getQueryStrings();
var reportNameParamValue = queryStrings["reportName"];
var pdfBitsUrl = "getReportPdfBits.aspx?reportName=" + reportNameParamValue;
// just in case PDF cannot be embedded, we'll fix the fallback link below:
var pdfFallbackLink = document.getElementById("pdfFallbackAnchor");
pdfFallbackLink.href = pdfFallbackLink;
// now perform the actual embed using PDFObject script from http://pdfobject.com
var success = new PDFObject( {
url: pdfBitsUrl;
}).embed();
};
</script>
</head>
<body>
<p>It appears you don't have Adobe Reader or PDF support in this web
browser. <a id="pdfFallbackAnchor" href="sample.pdf">Click here to download the PDF</a></p>
</body>

Why does my call from flash to Javascript fail in IE9?

I have a couple of buttons in my flash application that call two different javascript functions. They work in all browsers except IE9 (I haven't tried earlier IEs). My code to call the function is something like this:
ExternalInterface.call(
"myLovelyFunction",
string1, string2);
and the code in the JS looks like this:
function myLovelyFunction(string1, string2) {
window.open('https://twitter.com/share?url=http%3A%2F%2Fwww.mysite.com%2Fapage.php&via=atwitteraccount&text=Some%20text%22&related=atwitteraccount',
'windowname',
'height=290,width=510');
}
In IE9, the function does absolutely nothing, but the console complains with:
SCRIPT438: Object doesn't support property or method 'SetReturnValue'
index.php, line 1 character 1
line 1, character 1 is obviously pointing at nothing in particular.
I can make it work fine by switching on compatability view, although the console error doesn't go away.
Is there anything about IE9 that causes this, and more importantly, how do I fix this?
I had this very same issue as well. I was using the following code:
<object type="application/x-shockwave-flash" data="/files/banners/64/64_300x250.swf" width="300" height="250">
<param name="movie" value="/files/banners/64/64_300x250.swf"/>
<param name="wmode" value="transparent"/>
</object>
I'm just embedding the flash with a regular object tag (no SWFObject and no embed fallback). My flash file calls the JS function window.open via ExternalInterface like this:
ExternalInterface.call("window.open", url, target, features);
What didn't work:
The link above suggests changing it to "document.open", which did not work. Also attempting to force the page to render in IE-8 mode did not work. For example:
<meta http-equiv="X-UA-Compatible" content="IE=8" />
What did work: Simply adding a "name" and "id" to the object tag solved the issue. For example:
<object type="application/x-shockwave-flash" data="/files/banners/64/64_300x250.swf" width="300" height="250" name="flash_object" id="flash_object">
Had absolutely the same issue, link below helped to solve it.
http://msdn.microsoft.com/en-us/library/gg622942%28v=VS.85%29.aspx

External Interface Problem: Error calling method on NPObject

Making a flash video streaming web-app using Actionscript 3's external Api. I am at a very rudimentary phase of the project where we're just experimenting with external interface. Right now i just have a flash object and 3 buttons each to play pause and load a video. The only button that is currently set up to do anything is the load button. My swf and my html file sit on the same file system, and my video files sit on another server with traffic being redirected through a media server.
When i press the load button, which should just give it the path of the video file on it's server. Instead it throws an error that reads "Error: Error Calling method on NPObject".
Without further adieu, here are snippets of relevant code:
ACTIONSCRIPT:
function loadVideo(newVideo){
clearInterval(progressInterval);
videoFile = newVideo;
stream.play(videoFile, 0, 0);
videoPositions = "0,0";
};
ExternalInterface.addCallback( "loadVideo", loadVideo );
JAVSCRIPT: (in the head of my html document)
<head>
<title> External API Test</title>
<script type="text/javascript">
var player = getFlashMovie();
if (typeof MY == 'undefined')
{
MY = {};
}
MY.load = function()
{
console.log('load called');
getFlashMovie().loadVideo("/media/preview/09/04/38833_2_720X405.mp4");
};
function getFlashMovie()
{
var isIE = navigator.appName.indexOf('Microsoft') != -1;
return (isIE) ? window['MYVID'] : document['MYVID'];
}
</script>
</head>
HTML:(in same document as javascript)
<body>
<div> This is a test</div>
<div class='my-media-player'>
<object width="720" height="405" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,16,0" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id='MYVID'>
<param value="as3VideoPlayer.swf" name="movie">
<param value="high" name="quality">
<param value="true" name="play">
<param value="false" name="LOOP">
<param value="transparent" name="wmode">
<param value="always" name="allowScriptAccess">
<embed width="720" height="405" name='MYVID' allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" quality="high" loop="false" play="true" src="as3VideoPlayer.swf" wmode="transparent">
</object>
<div>
<button type="button" class='play'>Play</button>
<button type='button' class='pause'>Pause</button>
<button type='button' class='load' onclick='MY.load()'>Load</button>
</div>
</div>
</body>
Where is my mistake? I've read in a lot of places that this is an issue with security, but both my swf and html are in the same folder on my local machine. Only the files come from outside, and in any case I think i've set the security settings correctly when i declare my flash player in the object tag, but maybe i'm missing something there.
if you can't solve my question directly can someone please explain what "error calling method on NPObject" means? I'm sure its specific to flash-js communications because i've never seen it before and that's what i have gathered from my googling.
Thank in advanced.
I highly suggest SWFObject. Aside from that, I dare say you need to allow script access:
<script type="text/javascript">
// put your needed vars in the object below
var flashVars = {};
var params = {
allowScriptAccess:"always"
};
swfobject.embedSWF("myswf.swf", "myswf", "500", "400", "10.0.0", "", flashVars, params);
</script>
Can you try setting Security.allowDomain('*'); in your AS3 code right when it starts up?

Categories