Cross Domain ExternalInterface "Error calling method on NPObject" - javascript

I am trying to enable communication between Javascript and Flash via ExternalInterface across domains. The Javascript works great when it is located on the same domain as the SWF. But in one case, the HTML resides on domain A, the javascript and the flash both reside on domain B. I have done all of the following:
The embed tag has allowScriptAccess="always" (and the object has that as a param)
My SWF file's actionscipt has Security.allowDomain("*")
My SWF also calls Security.allowInsecureDomain("*")
Both domain A and domain B have a /crossdomain.xml file which has allow-access-from domain="*"
The SWF is able to call javascript on the page, but when I use Javascript to call functions exposed by ExternalInterface, I get
Error calling method on NPObject! [plugin exception: Error in Actionscript. Use a try/catch block to find error.]
This is ActionScript 2 so ExternalInterface.marshallExceptions is not available.

You should only need two things for this to work:
1) allowscriptaccess=always will allow your swf to send stuff out to the page
2) System.security.allowDomain("yourhtmldomain.com");
Note that it's System.security.allowDomain() in AS2 - it's not the same as AS3 or what you have written above.
number 2 above allows the html page on domainA to call things in the swf on domainB.
The domain your js is hosted on won't matter here, since the browser embeds it on domainA, the script is executed in domainA.
crossdomain.xml is mainly only for loading remote files, which you aren't doing, so you can remove that if you like. (and you probably don't want to have a crossdomain.xml file with allow="*" sitting on your main domain, that's very bad practice)

Since you are loading multiple swfs, you may need to include the security settings in each of those swfs on domain B that are loaded.
You may also need a loader context with the appropriate security settings.
import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.system.Security;
import flash.system.SecurityDomain;
import flash.net.URLRequest;
import flash.net.URLLoader;
var context:LoaderContext = new LoaderContext(true, ApplicationDomain.currentDomain, (Security.sandboxType == Security.REMOTE) ? SecurityDomain.currentDomain : null);
var l:Loader = new Loader();
l.load(new URLRequest("http://example.com/myswf.swf"), context);

for me a few reason was (i'm using uploadify):
http server haven't permission to write file to destination
swfobject (flash) haven't cross domain access
solution:
object tag in html must have allowScriptAccess="always" it can be done by set param like
$('#file_upload').uploadifySettings('scriptAccess', 'always')
than flash object must have:
import flash.system.Security;
Security.allowDomain('remotedomain.com');
it can be done by compile source with this param, i have that, if you need it write to me with uploadify subject.
Than Remote server, where flash include in the page, must have in the root crossdamoin.xml file with content like:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">

I had this same problem (allowDomain etc. were good), but I send to flash bad parameter - just outputed JSON from ajax call. Problem gone, when I put that json in "", and then parse it into javascript object (via jQuery.parseJSON).

Using AS3 with Flash Player version 10 I could not get ExternalInterface.addCallback() to work correctly for testing locally. I finally got my local copy working by adding the parameter "allowNetworking" with a value of "all" (http://www.adobe.com/livedocs/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001079.html). Good luck to anyone struggling with this!

In my case, it was because I was modifying the DOM element containing the uploader div.
I used the jquery hide() function to hide the div containing the uploader, and when I realized that caused the above error, I tried a different approach where I set the "float" attribute of the div. In both cases, it broke the uploader.
FWIW, it appears that setting the width/height of the div containing the uploader to 0 does NOT make the error occur.

Related

Embed external webpage inside html without iframe/ajax

I am working on Phonegap application and basically I want to embedd an external webpage inside my html page, yes for me various options are available. I tried with <iframe> method, but I am getting below error:
Refused to display 'https://xyz.com' in a frame because it set 'X-Frame-Options' to 'DENY'
Since I don't have control over the server side, loading an webpage inside an iframe is ruled out.
I also tried with ajax method:
$.ajax({
crossOrigin: true,
url: 'https://xyz.com',
success: function(data) {
$( '#bodyFrame' ).html(data);
}
});
It works fine, but the biggest problem is it doesn't render CSS/Javascript, it only displays plain html.
I tried with <link rel="import" href="https://xyz.com"> now I am getting cross-domain issue.
My question is, is there a way to display an external website inside an HTML page with correct css and js rendering (I don't have control on this part on server side) without IFrame/embed/object tags? I searched lot of questions on SO, most of them tell to use ajax but this have css issue. Can anyone help me in this?
Well, I think that you have at least few options.
Do like I just did for my project where I need to be able to show whole pages offline: load the HTML for that page, iterate through it (with regular expressions) to find out all resource links (JS, CSS, images) and download those (store to file system). Once downloaded, change the URL to URI of your local file on initial HTML. After that show that HTML for user.
Few special things to mention about this way in no particular order:
Implement cache of your own to speed this up.
Use blacklisting for URLs that you don't want to download.
caolan's Async.js library is just great for this.
For CSS resources you need still to download images within it and change the links to those too.
Images can be converted just to Base64 representation inside HTML for less callbacks to handle.
This way you can use the iframes.
This is pretty much related to first one but go through the HTML on your success callback and get all the links for JS and CSS and use technique described here to reload those for you.
Here is summary of that method:
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
document.getElementsByTagName("head")[0].appendChild(fileref);

Loading a script file in a Chrome App Sandbox

I'm working on a Chrome App, and I have a script file that's saved in the app's sandboxed filesystem. (It's available via a URL filesystem:chrome-extension_****/Persistent/script.js
I'm able to use Chrome's FileSystemAPI to read the file in the main app window. However, I need it to be accessible and executable in a sandboxed page.
I have the following in my manifest -
"sandbox": {
"pages": ["sandboxed_page.html"],
"content_security_policy": "sandbox allow-scripts;"
},
And I'm using the page like this:
<iframe id="sandbox_frame" seamless="seamless" src="sandboxed_page.html" sandbox="allow-scripts"></iframe>
I tried loading the file in the main app window, use window.URL.createObjectURL() to convert it to a blob: URL, and passed this URL via postMessage() to the sandbox. In the sandbox, I'm trying to load the URL into a <script> element. I get an error saying Not allowed to load local resource: blob:chrome-extension%3A//...
The other option (which is working) is load the contents of script.js in the main app, and send the entire string through postMessage(). Not sure this is a good idea, as script.js could get pretty big.
Am I doing something wrong, or is loading local scripts in sandboxes prohibited by Chrome's security policies?
I went through https://developer.chrome.com/apps/app_external, but there's no mention of sending the external resources to the sandbox.
Sandboxed pages execute in a unique origin i.e. one that is different from the App itself, and you can't access filesystem URLs across different origins. The same goes for object URLs created from those files.
You're basically stuck with the postMessage approach, though you may be able to make it more efficient by transfering it as an ArrayBuffer rather than copying the data as a string. See https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects).

Javascript detect which host it was loaded from

I have a Javascript library I'm working on. It can be self-hosted or run from another server. The script makes a number of AJAX calls and the preferred method is making POST requests to the same host as the including page. To allow for cross-domain calls it also supports JSONP, but this limits the amount of data that can be sent (~2K to safely accommodate most modern browsers' URL length limits).
Obviously the user including the script knows where they're getting it from and could manually select JSONP as needed, but in the interest of simplifying things, I'd like to detect, within the script itself, whether the script was loaded from the same host as the page including it or not.
I'm able to grab the script element with jQuery but doing a $('script').attr('src') is only returning a relative path (e.g. "/js/my-script.js" not "http://hostname.com/js/my-script.js") even when it's being loaded from a different host.
Is this possible and if so, how would I go about it?
Thanks in advance.
Don't use JSONP, use CORS headers.
But if you really want to do JS check, use var t = $('script')[0].outerHTML.
Effect on my page:
[20:43:34.865] "<script src="http://www.google-analytics.com/ga.js" async="" type="text/javascript"></script>"
Checking location.host should do the trick.

load cross domain xml by Javascript

Hi
Is it possible to load an XML file from a domain that differs from scripts domain with pure javascript and without using a php/asp/jsp/... script as proxy?
Something like xmlHttpRequest but with ability to manage cross domain requests.
Thanks
You can use something called JSONP. I know the name sucks, because it's not really related to JSON. But this requires you have control over the other domain. You need to wrap your XML inside a function call, or assign it to a javascript variable:
func('<xml></xml>');
or
var myxml = '<xml></xml>';
So if your other domain returns one of these two formats, you can use the <script src="http://otherdomain/yourjsonp"></script> syntax in your html to load that data in JavaScript. It's a little hacky but a lot of people use it.
It is possible with yql! (Yahoo did it for you)
Go to this site and simple at the "select from url='xxx' " replace the xxx with your xml url. Use the url created at the text box below and do a simple xmlrequest. You won't have any cross-domain prolems

use javascript to read a link resource without ajax

Not sure if it's possible but how do I read a resource from a url using javascript without ajax?
for example, the following url is a static text file containing json encoded text
http://mysite.s3.amazonaws.com/jsonencodedcontent.txt
I'd like to use javascript to read the content from above link, read the json content into a javascript variable.
I can't use ajax because of cross site and I have no control over amazon S3 domain.
anyway to achieve this?
Try #Ben's suggestion first. If for any reason that doesn't work in your case, here's two options I've both seen and used, which may or may not be available in your case (I'm providing two overly simplified examples just to clarify my points):
Create a server side resource that resides in your domain and retrieves and returns the cross site content for you:
<?php
die(file_get_contents('http://mysite.s3.amazonaws.com/jsonencodedcontent.txt'));
Use mod_rewrite (or something similar) to create a virtual resource in your domain that resolves to the remote content behind the scenes:
RewriteEngine On
RewriteRule ^jsonencodedcontext\.txt$ http://mysite.s3.amazonaws.com/jsonencodedcontent.txt [P]

Categories