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).
Related
I'm trying to load an html file into another html file for an app-project. Right now I'm doing it like this:
$.get('mod_navigation.html', function(data) { $('body').append(data);});
works as it should and is all I need :-) ... yet it does only work when i upload it on my server and test it via browser from there. Doing it via browser offline, so with the local files, the html file does not get included. Since the app later should work "offline" this does get me worried. How can I get this code to work offline/local?
Thanks in advance,
ANB_Seth
Can you use load()?
Load can work in localhost:
$('body').append($('<div id="nav">').load('mod_navigation.html'));
This appends a div to the body with the content (which is more common).
To replace the body entirely, just use:
$("body").load('mod_navigation.html');
Just remember that load paths from the root directory, not from the parent page's directory.
In localhost, there are restrictions. You will get a Access to restricted URI denied from a Get.
You could try JsonP or you could use HTML5 web app file storage.
Is there a way i can define my script tag to use absolute path instead of relative path so that my JavaScript files are loaded from a network location?
This is what i have tried:
<script src="file:\\\MyDFSDirectory\Test\TestApp\Scripts\jquery-1.7.1.js"></script>
This does not work. in FF, i get the error Security Error: Content at http://localhost/Test/Test.html may not load or link to file:\\\MyDFSDirectory\Test\TestApp\Scripts\jquery-1.7.1.js
In IE, I dont see the file being downloaded. In Network Tab (IE Dev Toolbar), it shows Received 0 B. If i take the URL and paste it in the File Explorer, it opens the JS file.
What am i missing here?
You are indeed running up against the security model of the browsers. The only way around this is to run a web server locally and serve up the files that way.
For development purposes, I'd like to be able to easily load locally-stored scripts into the browser instead of having to copy-paste to the console.
Creating a new <script> element isn't working, it gives a Not allowed to load local resource: file://.... error (in Chrome).
Also, creating a userscript won't work--I'd have to re-install it every time I make an edit.
Is there an alternative way to easily load a local script via a bookmarklet/etc?
In Chrome, you can create an extension that holds all of the local files that you need to load. It will make your files accessible via chrome-extension://... instead of file://...
Make a file named manifest.json in a new folder and fill it with:
{
"name": "File holder",
"manifest_version": 2,
"version": "1.0",
"web_accessible_resources": ["test.js", "other.js", "yetanother.js"]
}
Then, put all the scripts you want to load in that new directory, and make sure they are included in the web_accessbile_reources manifest list. Load the extension by going to chrome://extensions, enabling Developer Mode, and selecting the new folder with Load unpacked extension....
Now you can access all the files in your extension directory using chrome-extension://[app_id]/[file_name], where "app_id" is the hash listed for the extension on the chrome://extensions page. Note that because the protocols and hostnames differ from where you've doing your actual work (unless you decide to do all your development in the extension folder, which might be acceptable to you), the extension resources are cross-domain and can only be loaded via <script> tag.
Now from the console, you can do:
var s = document.createElement("script");
s.src = "chrome-extension://aefigdoelbemgaedgkcjpcnilbgagpcn/test.js";
document.body.appendChild(s);
(Assuming your file is test.js and your app id is aefigdoelbemgaedgkcjpcnilbgagpcn.)
It's a quite bit to type, I know, but perhaps you can store the chrome-extension://[app_id] part as a shorthand variable?
Sadly, Chrome doesn't allow you to load local files via AJAX; however, you can work around this limitation by launching the browser with the flag --disable-web-security (details vary per host operating system).
run chrome as:
chrome.exe --allow-file-access-from-files
from CLI
you need to run local http server
this is a good document for this:
https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server
Have you tried a relative path from your page to your js file liek so...
src='/js/javascript.js'
When an external JavaScript file is referenced,
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
is the JavaScript source (lines of code before interpretation) available from the DOM or window context in the current HTML page? I mean by using only standard JavaScript without any installed components or tools.
I know tools like Firebug trace into external source but it's installed on the platform and likely has special ability outside the context of the browser sandbox.
Nope. There's no Javascript API for loading the true content of <script> tags. This is actually not an oversight, but rather a security feature: suppose I request the .json file that Gmail requests via AJAX to load your inbox by putting it in an external <script> tag. A JSON document is valid Javascript (granted, without side-effects), so it would run without error. Then, if I could inspect the content of the external script, I would be able to read your e-mail. (I'm almost certain that Gmail is more complex than that, but most sites are not.)
So, making up a few things about how Gmail works, here's how the attack would look:
<script id="inbox" type="text/javascript" src="http://mail.google.com/OMGYOURINBOX.json"></script>
<script type="text/javascript">
// Supposing a value called `externalScriptContent` existed on a script tag:
var inboxJSON = document.getElementById('inbox').externalScriptContent;
var messages = JSON.parse(inboxJSON);
for(var i in messages) {
// Do something malicious with each e-mail message
alert(messages[i].body);
}
</script>
If a script tag had the value externalScriptContent, I could just put whatever URL in for the src that I wanted, and then summon up the remote file's contents, effectively circumventing AJAX cross-origin restrictions. That'd be bad. We allow cross-origin requests for remote scripts because they are run and run only. They cannot be read.
Firebug has these permissions because Firefox extensions have the ability to inspect anything that the browser requests; normal pages, thankfully, do not.
However! Bear in mind that, if the script is on your domain, instead of writing it in <script src="…"></script> form, you can pull it up with an AJAX request then eval it to have access to the contents and still only request it once :)
You can parse the <script> tag and re-request the js file by XMLHttpRequest, it will likely be readily served from cache and with credentials of the current page. But unless both your requesting script and the script in the tag originate from the same domain, the browser will disallow this.
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.