JavaScript in AIR
AIR makes several changes to the typical behavior of common JavaScript objects. Many of these changes are made to make it easier to write secure applications in AIR. At the same time, these differences in behavior mean that some common JavaScript coding patterns, and existing web applications using those patterns, might not always execute as expected in AIR. For information on correcting these types of issues, see Avoiding security-related JavaScript errors.
HTML Sandboxes
AIR places content into isolated sandboxes according to the origin of the content. The sandbox rules are consistent with the same-origin policy implemented by most web browsers, as well as the rules for sandboxes implemented by the Adobe Flash Player. In addition, AIR provides a new application sandbox type to contain and protect application content. See Security sandboxes for more information on the types of sandboxes you may encounter when developing AIR applications.
Access to the run-time environment and AIR APIs are only available to HTML and JavaScript running within the application sandbox. At the same time, however, dynamic evaluation and execution of JavaScript, in its various forms, is largely restricted within the application sandbox for security reasons. These restrictions are in place whether or not your application actually loads information directly from a server. (Even file content, pasted strings, and direct user input may be untrustworthy.)
The origin of the content in a page determines the sandbox to which it is
consigned. Only content loaded from the application directory (the installation
directory referenced by the app:
URL scheme) is placed in the application
sandbox. Content loaded from the file system is placed in the local-with-file
system or the local-trusted sandbox, which allows access and interaction with
content on the local file system, but not remote content. Content loaded from
the network is placed in a remote sandbox corresponding to its domain of origin.
To allow an application page to interact freely with content in a remote sandbox, the page can be mapped to the same domain as the remote content. For example, if you write an application that displays map data from an Internet service, the page of your application that loads and displays content from the service could be mapped to the service domain. The attributes for mapping pages into a remote sandbox and domain are new attributes added to the frame and iframe HTML elements.
To allow content in a non-application sandbox to safely use AIR features, you can set up a parent sandbox bridge. To allow application content to safely call methods and access properties of content in other sandboxes, you can set up a child sandbox bridge. Safety here means that remote content cannot accidentally get references to objects, properties, or methods that are not explicitly exposed. Only simple data types, functions, and anonymous objects can be passed across the bridge. However, you must still avoid explicitly exposing potentially dangerous functions. If, for example, you exposed an interface that allowed remote content to read and write files anywhere on a user's system, then you might be giving remote content the means to do considerable harm to your users.
JavaScript eval() function
Use of the eval()
function is restricted within the application sandbox once a
page has finished loading. Some uses are permitted so that JSON-formatted data
can be safely parsed, but any evaluation that results in executable statements
results in an error.
Code restrictions for content in different sandboxes
describes the allowed uses of the eval()
function.
Function constructors
In the application sandbox, function constructors can be used before a page has
finished loading. After all page load
event handlers have finished, new
functions cannot be created.
Loading external scripts
HTML pages in the application sandbox cannot use the script
tag to load
JavaScript files from outside of the application directory. For a page in your
application to load a script from outside the application directory, the page
must be mapped to a non-application sandbox.
The XMLHttpRequest object
AIR provides an XMLHttpRequest (XHR) object that applications can use to make data requests. The following example illustrates a simple data request:
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http:/www.example.com/file.data", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
//do something with data...
}
}
xmlhttp.send(null);
In contrast to a browser, AIR allows content running in the application sandbox to request data from any domain. The result of an XHR that contains a JSON string can be evaluated into data objects unless the result also contains executable code. If executable statements are present in the XHR result, an error is thrown and the evaluation attempt fails.
To prevent accidental injection of code from remote sources, synchronous XHRs return an empty result if made before a page has finished loading. Asynchronous XHRs will always return after a page has loaded.
By default, AIR blocks cross-domain XMLHttpRequests in non-application
sandboxes. A parent window in the application sandbox can choose to allow
cross-domain requests in a child frame containing content in a non-application
sandbox by setting allowCrossDomainXHR
, an attribute added by AIR, to true
in the containing frame or iframe element:
<iframe id="mashup"
src="http://www.example.com/map.html"
allowCrossDomainXHR="true">
</iframe>
Note: When convenient, the AIR URLStream class can also be used to download data.
If you dispatch an XMLHttpRequest to a remote server from a frame or iframe containing application content that has been mapped to a remote sandbox, make sure that the mapping URL does not mask the server address used in the XHR. For example, consider the following iframe definition, which maps application content into a remote sandbox for the example.com domain:
<iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/"
allowCrossDomainXHR="true">
</iframe>
Because the sandboxRoot
attribute remaps the root URL of the www.example.com
address, all requests are loaded from the application directory and not the
remote server. Requests are remapped whether they derive from page navigation or
from an XMLHttpRequest.
To avoid accidentally blocking data requests to your remote server, map the
sandboxRoot
to a subdirectory of the remote URL rather than the root. The
directory does not have to exist. For example, to allow requests to the
www.example.com to load from the remote server rather than the application
directory, change the previous iframe to the following:
<iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"
allowCrossDomainXHR="true">
</iframe>
In this case, only content in the air
subdirectory is loaded locally.
For more information on sandbox mapping see HTML frame and iframe elements and HTML security in Adobe AIR.
Cookies
In AIR applications, only content in remote sandboxes (content loaded from http:
and https: sources) can use cookies (the document.cookie
property). In the
application sandbox, other means for storing persistent data are available,
including the EncryptedLocalStore, SharedObject, and FileStream classes.
The Clipboard object
The WebKit Clipboard API is driven with the following events: copy
, cut
, and
paste
. The event object passed in these events provides access to the
clipboard through the clipboardData
property. Use the following methods of the
clipboardData
object to read or write clipboard data:
Method | Description |
---|---|
clearData(mimeType) | Clears the clipboard data. Set the mimeType parameter to the MIME type of the data to clear. |
getData(mimeType) | Get the clipboard data. This method can only be called in a handler for the paste event. Set the mimeType parameter to the MIME type of the data to return. |
setData(mimeType, data) | Copy data to the clipboard. Set the mimeType parameter to the MIME type of the data. |
JavaScript code outside the application sandbox can only access the clipboard through theses events. However, content in the application sandbox can access the system clipboard directly using the AIR Clipboard class. For example, you could use the following statement to get text format data on the clipboard:
var clipping = air.Clipboard.generalClipboard.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
The valid data MIME types are:
MIME type | Value |
---|---|
Text | "text/plain" |
HTML | "text/html" |
URL | "text/uri-list" |
Bitmap | "image/x-vnd.adobe.air.bitmap" |
File list | "application/x-vnd.adobe.air.file-list" |
Important: Only content in the application sandbox can access file data present on the clipboard. If non-application content attempts to access a file object from the clipboard, a security error is thrown.
For more information on using the clipboard, see Copy and paste and Using the Pasteboard from JavaScript (Apple Developer Center).
Drag and Drop
Drag-and-drop gestures into and out of HTML produce the following DOM events:
dragstart
, drag
, dragend
, dragenter
, dragover
, dragleave
, and
drop
. The event object passed in these events provides access to the dragged
data through the dataTransfer
property. The dataTransfer
property references
an object that provides the same methods as the clipboardData
object
associated with a clipboard event. For example, you could use the following
function to get text format data from a drop
event:
function onDrop(dragEvent){
return dragEvent.dataTransfer.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
}
The dataTransfer
object has the following important members:
Member | Description |
---|---|
clearData(mimeType) | Clears the data. Set the mimeType parameter to the MIME type of the data representation to clear. |
getData(mimeType) | Get the dragged data. This method can only be called in a handler for the drop event. Set the mimeType parameter to the MIME type of the data to get. |
setData(mimeType, data) | Set the data to be dragged. Set the mimeType parameter to the MIME type of the data. |
types | An array of strings containing the MIME types of all data representations currently available in the dataTransfer object. |
effectsAllowed | Specifies whether the data being dragged can be copied, moved, linked, or some combination thereof. Set the effectsAllowed property in the handler for the dragstart event. |
dropEffect | Specifies which of the allowed drop effects are supported by a drag target. Set the dropEffect property in the handler for the dragEnter event. During the drag, the cursor changes to indicate which effect would occur if the user released the mouse. If no dropEffect is specified, an effectsAllowed property effect is chosen. The copy effect has priority over the move effect, which itself has priority over the link effect. The user can modify the default priority using the keyboard. |
For more information on adding support for drag-and-drop to an AIR application see Drag and drop in AIR and Using the Drag-and-Drop from JavaScript (Apple Developer Center).
innerHTML and outerHTML properties
AIR places security restrictions on the use of the innerHTML
and outerHTML
properties for content running in the application sandbox. Before the page load
event, as well as during the execution of any load event handlers, use of the
innerHTML
and outerHTML
properties is unrestricted. However, once the page
has loaded, you can only use innerHTML
or outerHTML
properties to add static
content to the document. Any statement in the string assigned to innerHTML
or
outerHTML
that evaluates to executable code is ignored. For example, if you
include an event callback attribute in an element definition, the event listener
is not added. Likewise, embedded <script>
tags are not evaluated. For more
information, see the
HTML security in Adobe AIR.
Document.write() and Document.writeln() methods
Use of the write()
and writeln()
methods is not restricted in the
application sandbox before the load
event of the page. However, once the page
has loaded, calling either of these methods does not clear the page or create a
new one. In a non-application sandbox, as in most web browsers, calling
document.write()
or writeln()
after a page has finished loading clears the
current page and opens a new, blank one.
Document.designMode property
Set the document.designMode
property to a value of on
to make all elements
in the document editable. Built-in editor support includes text editing, copy,
paste, and drag-and-drop. Setting designMode
to on
is equivalent to setting
the contentEditable
property of the body
element to true
. You can use the
contentEditable
property on most HTML elements to define which sections of a
document are editable. See
HTML contentEditable attribute
for additional information.
unload events (for body and frameset objects)
In the top-level frameset
or body
tag of a window (including the main window
of the application), do not use the unload
event to respond to the window (or
application) being closed. Instead, use exiting
event of the NativeApplication
object (to detect when an application is closing). Or use the closing
event of
the NativeWindow object (to detect when a window is closing). For example, the
following JavaScript code displays a message ( "Goodbye."
) when the user
closes the application:
var app = air.NativeApplication.nativeApplication;
app.addEventListener(air.Event.EXITING, closeHandler);
function closeHandler(event)
{
alert("Goodbye.");
}
However, scripts can successfully respond to the unload
event caused by
navigation of a frame, iframe, or top-level window content.
Note: These limitations may be removed in a future version of Adobe AIR.
JavaScript Window object
The Window object remains the global object in the JavaScript execution context. In the application sandbox, AIR adds new properties to the JavaScript Window object to provide access to the built-in classes of AIR, as well as important host objects. In addition, some methods and properties behave differently depending on whether they are within the application sandbox or not.
Window.runtime property
The runtime
property allows you to instantiate and use the built-in runtime
classes from within the application sandbox. These classes include the AIR and
Flash Player APIs (but not, for example, the Flex framework). For example, the
following statement creates an AIR file object:
var preferencesFile = new window.runtime.flash.filesystem.File();
The AIRAliases.js
file, provided in the AIR SDK, contains alias definitions
that allow you to shorten such references. For example, when AIRAliases.js
is
imported into a page, a File object can be created with the following statement:
var preferencesFile = new air.File();
The window.runtime
property is only defined for content within the application
sandbox and only for the parent document of a page with frames or iframes.
See Using the AIRAliases.js file.
Window.nativeWindow property
The nativeWindow
property provides a reference to the underlying native window
object. With this property, you can script window functions and properties such
as screen position, size, and visibility, and handle window events such as
closing, resizing, and moving. For example, the following statement closes the
window:
window.nativeWindow.close();
Note: The window control features provided by the NativeWindow object overlap the features provided by the JavaScript Window object. In such cases, you can use whichever method you find most convenient.
The window.nativeWindow
property is only defined for content within the
application sandbox and only for the parent document of a page with frames or
iframes.
Window.htmlLoader property
The htmlLoader
property provides a reference to the AIR HTMLLoader object that
contains the HTML content. With this property, you can script the appearance and
behavior of the HTML environment. For example, you can use the
htmlLoader.paintsDefaultBackground
property to determine whether the control
paints a default, white background:
window.htmlLoader.paintsDefaultBackground = false;
Note: The HTMLLoader object itself has a window
property, which references the
JavaScript Window object of the HTML content it contains. You can use this
property to access the JavaScript environment through a reference to the
containing HTMLLoader.
The window.htmlLoader
property is only defined for content within the
application sandbox and only for the parent document of a page with frames or
iframes.
Window.parentSandboxBridge and Window.childSandboxBridge properties
The parentSandboxBridge
and childSandboxBridge
properties allow you to
define an interface between a parent and a child frame. For more information,
see
Cross-scripting content in different security sandboxes.
Window.setTimeout() and Window.setInterval() functions
AIR places security restrictions on use of the setTimeout()
and
setInterval()
functions within the application sandbox. You cannot define the
code to be executed as a string when calling setTimeout()
or setInterval()
.
You must use a function reference. For more information, see
setTimeout() and setInterval().
Window.open() function
When called by code running in a non-application sandbox, the open()
method
only opens a window when called as a result of user interaction (such as a mouse
click or keypress). In addition, the window title is prefixed with the
application title (to prevent windows opened by remote content from
impersonating windows opened by the application). For more information, see the
Restrictions on calling the JavaScript window.open() method.
air.NativeApplication object
The NativeApplication object provides information about the application state,
dispatches several important application-level events, and provides useful
functions for controlling application behavior. A single instance of the
NativeApplication object is created automatically and can be accessed through
the class-defined NativeApplication.nativeApplication
property.
To access the object from JavaScript code you could use:
var app = window.runtime.flash.desktop.NativeApplication.nativeApplication;
Or, if the AIRAliases.js
script has been imported, you could use the shorter
form:
var app = air.NativeApplication.nativeApplication;
The NativeApplication object can only be accessed from within the application sandbox. For more information about the NativeApplication object, see Working with AIR runtime and operating system information.
The JavaScript URL scheme
Execution of code defined in a JavaScript URL scheme (as in
href="javascript:alert('Test')"
) is blocked within the application sandbox. No
error is thrown.