AIR apporte plusieurs modifications au comportement classique des objets JavaScript courants. La plupart de ces modifications sont destinées à simplifier l’écriture d’applications sécurisées dans AIR. Parallèlement à cela, ces différences de comportement impliquent que certains modèles de codage JavaScript courants et les applications Web existantes qui s’en servent risquent de ne pas fonctionner comme prévu dans AIR. Pour plus d’informations sur la correction de ces types de problèmes, voir la section
Contournement des erreurs JavaScript liées à la sécurité
.
Sandbox HTML
AIR place les différents contenus dans des sandbox distincts en fonction de leur origine. Les règles de sandbox respectent la stratégie de « même origine » implémentée par la plupart des navigateurs Web, de même que les règles applicables aux sandbox mises en œuvre par Adobe Flash Player. AIR propose en outre un nouveau type de sandbox d’
application
conçu pour contenir et protéger le contenu de l’application. Pour plus d’informations sur les types de sandbox que vous êtes susceptible de rencontrer lors du développement d’applications AIR, voir
Sandbox de sécurité
.
L’accès à l’environnement d’exécution et aux API AIR est uniquement disponible pour les scripts HTML et JavaScript exécutés dans le sandbox de l’application. Parallèlement à cela, toutefois, les opérations d’évaluation et d’exécution dynamiques de code JavaScript, sous leurs diverses formes, sont largement limitées au sein du sandbox de l’application pour des raisons de sécurité. Ces restrictions s’appliquent que votre application charge réellement ou non des informations directement depuis un serveur. (Même le contenu des fichiers, les chaînes collées et les données saisies directement par l’utilisateur peuvent ne pas être fiables.)
L’origine du contenu d’une page détermine le sandbox associé au contenu. Seul le contenu chargé à partir du répertoire de l’application (le répertoire d’installation auquel le modèle d’URL
app:
fait référence) est placé dans le sandbox de l’application. Tout contenu chargé à partir du système de fichiers est placé dans le sandbox
local avec système de fichiers
ou le sandbox de sécurité
approuvé localement
, lequel permet d’accéder au contenu situé sur le système de fichiers local (mais pas au contenu distant) et d’interagir avec lui. Tout contenu chargé à partir du réseau est dirigé vers un sandbox distant correspondant à son domaine d’origine.
Pour qu’une page d’application puisse interagir librement avec un contenu situé dans un sandbox distant, vous pouvez la mapper au même domaine que le contenu distant. Si, par exemple, vous écrivez une application affichant des données de mappage provenant d’un service Internet, la page de l’application qui est chargée et qui présente le contenu émanant du service pourrait être mappée au domaine du service. Les attributs de mappage des pages dans un sandbox et un domaine distants sont de nouveaux attributs ajoutés aux éléments image et iframe HTML.
Pour permettre à un contenu d’un sandbox autre que d’application d’utiliser les fonctions d’AIR en toute sécurité, vous pouvez configurer un pont de sandbox parent. Pour permettre au contenu de l’application d’appeler des méthodes et des propriétés d’accès de contenu en toute sécurité dans d’autres sandbox, configurez un pont de sandbox enfant. La notion de sécurité évoquée ici signifie que le contenu distant ne peut pas obtenir accidentellement de références à des objets, des propriétés ou des méthodes exposés de manière non explicite. Seuls les objets anonymes, fonctions et types de données simples peuvent être transmis via le pont. Vous devez néanmoins éviter d’exposer explicitement des fonctions potentiellement dangereuses. Si, par exemple, vous avez exposé une interface qui autorisait le contenu distant à lire et à écrire des fichiers n’importe où sur le système d’un utilisateur, vous risquez de donner à ce contenu les moyens de nuire considérablement aux utilisateurs.
Fonction eval() JavaScript
L’utilisation de la fonction
eval()
est limitée au contenu du sandbox de l’application une fois le téléchargement de la page terminé. Dans certains cas, cette fonction peut servir à analyser en toute sécurité des données au format JSON, mais toute évaluation aboutissant à des résultats d’instructions exécutables se traduit par une erreur. La section
Restrictions relatives au code pour un contenu dans des sandbox différents
décrit les utilisations autorisées pour la fonction
eval()
.
Constructeurs de fonctions
Dans le sandbox d’application, il est possible d’utiliser des constructeurs de fonctions avant la fin du chargement d’une page. Dès lors que tous les gestionnaires d’événement
load
de page sont terminés, il est impossible de créer de nouvelles fonctions.
Chargement d’un script externe
Les pages HTML du sandbox de l’application ne peuvent pas utiliser la balise
script
pour charger des fichiers JavaScript situés en dehors du répertoire de l’application. Pour qu’une page de votre application puisse charger un script stocké en dehors du répertoire de l’application, vous devez la mapper dans un sandbox autre que celui de d’application.
Objet XMLHttpRequest
AIR fournit un objet XMLHttpRequest (XHR) dont les applications peuvent se servir pour émettre des requêtes de données. L’exemple suivant illustre une demande de données simple :
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);
Contrairement à un navigateur, AIR permet au contenu exécuté dans le sandbox de l’application de demander des données provenant de n’importe quel domaine. Le résultat d’une requête XHR contenant une chaîne JSON peut aboutir à des objets de données à moins de comprendre également du code exécutable. Si des instructions exécutables figurent dans le résultat de la requête XHR, une erreur est renvoyée et la tentative d’évaluation se solde par un échec.
Pour empêcher l’introduction accidentelle de code provenant de sources distantes, les requêtes XHR synchrones renvoient un résultat vide lorsqu’elles sont émises avant la fin du chargement de la page. Les requêtes XHR asynchrones sont toujours renvoyées après le chargement d’une page.
Par défaut, AIR bloque les requêtes XMLHttpRequest interdomaines dans les sandbox autres que d’application. Une fenêtre parent du sandbox de l’application peut choisir d’autoriser des requêtes interdomaines dans une image enfant dont le contenu ne se trouve pas dans un sandbox autre que d’application. Pour ce faire, définissez
allowCrossDomainXHR
, un attribut ajouté par AIR, sur la valeur
true
dans l’élément image ou iframe conteneur :
<iframe id="mashup"
src="http://www.example.com/map.html"
allowCrossDomainXHR="true"
</iframe>
Remarque :
si cela s’avère pratique, il est aussi possible de télécharger les données à l’aide de la classe URLStream AIR.
Si vous distribuez une requête XMLHttpRequest vers un serveur distant à partir d’une image ou d’une iframe doté du contenu de l’application mappé dans un sandbox distant, assurez-vous que l’URL de mappage ne masque pas l’adresse du serveur utilisé dans la requête XHR. Tenez compte, par exemple, de la définition d’iframe suivante, laquelle mappe le contenu de l’application dans un sandbox distant pour le domaine example.com :
<iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/"
allowCrossDomainXHR="true"
</iframe>
Etant donné que l’attribut
sandboxRoot
remappe l’URL racine de l’adresse www.example.com, toutes les requêtes sont chargées à partir du répertoire de l’application et non du serveur distant. Les requêtes sont remappées, qu’elles soient issues de la navigation dans les pages ou d’une requête XMLHttpRequest.
Afin d’éviter de bloquer accidentellement des requêtes de données en direction du serveur distant, mappez
sandboxRoot
à un sous-répertoire de l’URL distante plutôt qu’à la racine. Le répertoire ne doit pas nécessairement exister. Par exemple, pour permettre le chargement des requêtes en direction de www.example.com à partir du serveur distant plutôt que du répertoire de l’application, modifiez l’iframe précédente de la manière suivante :
<iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"
allowCrossDomainXHR="true"
</iframe>
Dans ce cas, seul le contenu du sous-répertoire
air
est chargé en local.
Pour plus d’informations sur le mappage de sandbox, voir
Eléments image et iframe HTML
et
Sécurité HTML dans Adobe AIR
.
Cookies
Dans les applications AIR, seul le contenu des sandbox distants (chargé à partir de sources http: et https:) peut utiliser des cookies (propriété
document.cookie
). Le sandbox d’application propose d’autres techniques de stockage des données persistantes, telles que les classes EncryptedLocalStore, SharedObject et FileStream.
Objet Clipboard
L’API Clipboard de WebKit est dotée des événements suivants :
copy
,
cut
et
paste
. L’objet événement transmis dans ces événements permet d’accéder au Presse-papiers via la propriété
clipboardData
. Faites appel aux méthodes suivantes de l’objet
clipboardData
pour lire ou écrire des données de Presse-papiers :
Méthode
|
Description
|
clearData(mimeType)
|
Efface les données du Presse-papiers. Définissez le paramètre
mimeType
sur le type MIME des données à effacer.
|
getData(mimeType)
|
Permet d’obtenir les données du Presse-papiers. Cette méthode peut uniquement être appelée dans un gestionnaire pour l’événement
paste
. Définissez le paramètre
mimeType
sur le type MIME des données à renvoyer.
|
setData(mimeType, data)
|
Copie les données dans le Presse-papiers. Définissez le paramètre
mimeType
sur le type MIME des données.
|
Le code JavaScript situé en dehors du sandbox de l’application peut uniquement accéder au Presse-papiers par le biais de ces événements. Toutefois, le contenu du sandbox de l’application a la possibilité d’accéder directement au Presse-papiers du système à l’aide de la classe Clipboard AIR. Par exemple, l’instruction suivante pourrait servir à obtenir des données au format texte du Presse-papiers :
var clipping = air.Clipboard.generalClipboard.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
Les types MIME de données valides sont les suivants :
Type MIME
|
Valeur
|
Texte
|
"text/plain"
|
HTML
|
"text/html"
|
URL
|
"text/uri-list"
|
Image bitmap
|
"image/x-vnd.adobe.air.bitmap"
|
Liste de fichiers
|
"application/x-vnd.adobe.air.file-list"
|
Important :
seul le contenu du sandbox de l’application peut accéder aux données de fichier stockées dans le Presse-papiers. Si du contenu hors application tente d’accéder à un objet fichier du Presse-papiers, une erreur de sécurité est générée.
Pour plus d’informations sur l’utilisation du Presse-papiers, voir
Opération de copier-coller
et
Using the Pasteboard from JavaScript (centre des développeurs Apple)
.
Opération glisser-déposer
Les mouvements de glisser-déposer vers et depuis un contenu HTML génèrent les événements DOM suivants :
dragstart
,
drag
,
dragend
,
dragenter
,
dragover
,
dragleave
et
drop
. L’objet événement transmis dans ces événements permet d’accéder aux données déplacées via la propriété
dataTransfer
. La propriété
dataTransfer
fait référence à un objet offrant les mêmes méthodes que l’objet
clipboardData
associé à un événement clipboard. Par exemple, la fonction suivante pourrait servir à obtenir des données au format texte à partir d’un événement
drop
:
function onDrop(dragEvent){
return dragEvent.dataTransfer.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
}
L’objet
dataTransfer
dispose des membres importants suivants :
Membre
|
Description
|
clearData(mimeType)
|
Efface les données. Définissez le paramètre
mimeType
sur le type MIME de la représentation de données à effacer.
|
getData(mimeType)
|
Permet d’obtenir les données que vous avez fait glisser. Cette méthode peut uniquement être appelée dans un gestionnaire pour l’événement
drop
. Définissez le paramètre
mimeType
sur le type MIME des données à obtenir.
|
setData(mimeType, data)
|
Définit les données à faire glisser. Définissez le paramètre
mimeType
sur le type MIME des données.
|
types
|
Tableau de chaînes contenant les types MIME de toutes les représentations de données actuellement disponibles dans l’objet
dataTransfer
.
|
effectsAllowed
|
Indique si les données que vous faites glisser peuvent être copiées, déplacées et/ou liées. Définissez la propriété
effectsAllowed
du gestionnaire pour l’événement
dragstart
.
|
dropEffect
|
Indique, parmi les effets de type drop (déposer) autorisés, ceux qui sont pris en charge par une cible de type drag (glisser). Définissez la propriété
dropEffect
du gestionnaire pour l’événement
dragEnter
. Au cours du glissement, le curseur change de forme afin d’indiquer l’effet qui se produirait si l’utilisateur relâchait le bouton de la souris. Si aucun effet
dropEffect
n’est spécifié, un effet doté de la propriété
effectsAllowed
est appliqué. L’effet copy (copier) est prioritaire sur l’effet move (déplacer), lequel a priorité sur l’effet link (lier). L’utilisateur peut modifier le niveau de priorité par défaut au moyen du clavier.
|
Pour plus d’informations sur l’ajout de la prise en charge du glisser-déposer à une application AIR, voir
Opération glisser-déposer dans AIR
et
Using the Drag-and-Drop from JavaScript (centre de développeurs Apple)
.
Propriétés innerHTML et outerHTML
Pour des raisons de sécurité, AIR limite l’utilisation des propriétés
innerHTML
et
outerHTML
avec un contenu exécuté dans le sandbox de l’application. Avant l’événement de chargement de la page, de même que pendant l’exécution de tout gestionnaire d’événement de chargement, l’utilisation des propriétés
innerHTML
et
outerHTML
n’est pas restreinte. Toutefois, dès lors que la page est chargée, vous pouvez uniquement vous servir des propriétés
innerHTML
ou
outerHTML
afin d’ajouter un contenu statique au document. Toute instruction de la chaîne attribuée à
innerHTML
ou à
outerHTML
qui aboutit à du code exécutable est ignorée. Si, par exemple, vous incluez un attribut de rappel d’événement dans une définition d’élément, l’écouteur d’événement n’est pas inséré. De la même manière, les balises
<script>
intégrées ne sont pas évaluées. Pour plus d’informations, voir
Sécurité HTML dans Adobe AIR
.
Méthodes Document.write() et Document.writeln()
L’utilisation des méthodes
write()
et
writeln()
n’est pas limitée dans le sandbox de l’application avant la survenue de l’événement
load
de la page. Toutefois, dès lors que la page est chargée, l’appel de l’une ou l’autre de ces méthodes n’efface pas la page ou n’en crée pas de nouvelle. Dans un sandbox autre que celui de l’application, comme dans la plupart des navigateurs Web, l’appel de la méthode
document.write()
ou
writeln()
après la fin du chargement de la page entraîne l’effacement de la page active et l’ouverture d’une nouvelle page vide.
Propriété Document.designMode
Définissez la propriété
document.designMode
sur la valeur
on
afin de rendre tous les éléments du document modifiables. L’éditeur intégré prend en charge les modifications de texte, la copie, le collage et le glisser-déposer. Définir
designMode
sur
on
revient au même que configurer la propriété
contentEditable
de l’élément
body
sur la valeur
true
. La propriété
contentEditable
permet de définir les sections modifiables d’un document pour la plupart des éléments HTML. Pour plus d’informations, voir la section
Attribut contentEditable HTML
.
Evénements unload (pour les objets body et frameset)
Dans la balise
frameset
ou
body
de niveau supérieur d’une fenêtre (y compris la fenêtre principale de l’application), ne répondez pas à la fenêtre (ou à l’application) en cours de fermeture au moyen de l’événement
unload
. Au lieu de cela, optez pour l’événement
exiting
de l’objet NativeApplication (afin de détecter le moment de fermeture d’une application). Une autre solution consiste à utiliser l’événement
closing
de l’objet NativeWindow (afin de détecter le moment de fermeture d’une fenêtre). Par exemple, le code JavaScript suivant affichage un message (
« Goodbye »
) lorsque l’utilisateur ferme l’application :
var app = air.NativeApplication.nativeApplication;
app.addEventListener(air.Event.EXITING, closeHandler);
function closeHandler(event)
{
alert("Goodbye.");
}
Toutefois, les scripts
peuvent
réagir correctement à l’événement
unload
déclenché par la navigation dans une image, une iframe ou le contenu d’une fenêtre de niveau supérieur.
Remarque :
il est probable que ces limitations soient supprimées dans une prochaine version d’Adobe AIR.
Objet Window JavaScript
L’objet Window reste l’objet global dans le contexte d’exécution JavaScript. Dans le sandbox de l’application, AIR insère de nouvelles propriétés dans l’objet Window JavaScript en vue d’offrir un accès aux classes intégrées d’AIR de même qu’à des objets hôte importants. En outre, certaines méthodes et propriétés se comportent différemment selon qu’elles se trouvent dans le sandbox de l’application ou pas.
-
Propriété Window.runtime
-
La propriété
runtime
vous permet d’instancier et d’utiliser les classes d’exécution intégrées à partir du sandbox de l’application. Ces classes comprennent les API AIR et Flash Player (mais pas, par exemple, la structure Flex). L’instruction suivante crée par exemple un objet de fichier AIR :
var preferencesFile = new window.runtime.flash.filesystem.File();
Le fichier
AIRAliases.js
, disponible dans le kit SDK d’AIR, contient des définitions d’alias permettant de raccourcir de telles références. Ainsi, lorsque le fichier
AIRAliases.js
est importé dans une page, il est possible de créer un objet File à l’aide de l’instruction suivante :
var preferencesFile = new air.File();
La propriété
window.runtime
est exclusivement définie pour un contenu situé dans le sandbox de l’application et uniquement pour le document parent d’une page dotée d’images ou d’iframes.
Voir la section
Utilisation du fichier AIRAliases.js
.
-
Propriété Window.nativeWindow
-
La propriété
nativeWindow
fournit une référence à l’objet window natif sous-jacent. Grâce à cette propriété, vous pouvez coder des fonctions et propriétés de fenêtre (window) telles que la position, la taille et la visibilité, et gérer des événements de fenêtre comme la fermeture, le redimensionnement et le déplacement. Dans l’exemple suivant, l’instruction permet de fermer la fenêtre :
window.nativeWindow.close();
Remarque :
les fonctions de contrôle de la fenêtre fournies par l’objet NativeWindow chevauchent celles fournies par l’objet Window JavaScript. Dans de tels cas, vous pouvez opter pour la méthode qui vous semble la plus pratique.
La propriété
window.nativeWindow
est exclusivement définie pour un contenu situé dans le sandbox de l’application et pour le document parent d’une page dotée d’images ou d’iframes.
-
Propriété Window.htmlLoader
-
La propriété
htmlLoader
fournit une référence à l’objet HTMLLoader AIR disposant du contenu HTML. Grâce à cette propriété, vous pouvez coder l’aspect et le comportement de l’environnement HTML. Vous pouvez ainsi utiliser la propriété
htmlLoader.paintsDefaultBackground
afin de déterminer si la commande dessine un arrière-plan blanc par défaut :
window.htmlLoader.paintsDefaultBackground = false;
Remarque :
l’objet HTMLLoader proprement dit est doté d’une propriété
window
, laquelle fait référence à l’objet Window JavaScript du contenu HTML inclus. Cette propriété vous permet d’accéder à l’environnement JavaScript via une référence à l’objet HTMLLoader conteneur.
La propriété
window.htmlLoader
est exclusivement définie pour un contenu situé dans le sandbox de l’application et pour le document parent d’une page dotée d’images ou d’iframes.
-
Propriétés Window.parentSandboxBridge et Window.childSandboxBridge
-
Les propriétés
parentSandboxBridge
et
childSandboxBridge
vous permettent de définir une interface entre un cadre parent et un cadre enfant. Pour plus d’informations, voir la section
Programmation croisée du contenu dans des sandbox de sécurité distincts
.
-
Fonctions Window.setTimeout() et Window.setInterval()
-
Pour des raisons de sécurité, AIR limite l’utilisation des fonctions
setTimeout()
et
setInterval()
dans le sandbox de l’application. Il est impossible de définir le code à exécuter sous forme de chaîne lors de l’appel de la fonction
setTimeout()
ou
setInterval()
. Vous devez impérativement utiliser une référence à la fonction. Pour plus d’informations, voir la section
setTimeout() et setInterval()
.
-
Fonction Window.open()
-
Lorsqu’elle est appelée par du code exécuté dans un sandbox autre que d’application, la méthode
open()
ouvre seulement une fenêtre si elle est appelée suite à une action utilisateur (telle qu’un clic de souris ou l’activation d’une touche du clavier). De plus, le titre de la fenêtre est précédé du titre de l’application (afin d’empêcher l’ouverture de fenêtres par du contenu distant provenant de fenêtres d’usurpation d’identité ouvertes par l’application). Pour plus d’informations, voir la section
Restrictions relatives à l’appel de la méthode window.open() de JavaScript
.
Objet air.NativeApplication
L’objet NativeApplication fournit des informations sur l’état de l’application, distribue différents événements de niveau application importants et offre des fonctions pratiques de contrôle du comportement de l’application. Une occurrence unique de l’objet NativeApplication est créée automatiquement. Elle est accessible via la propriété
NativeApplication.nativeApplication
définie dans la classe.
Pour accéder à l’objet à partir du code JavaScript, vous pouvez utiliser :
var app = window.runtime.flash.desktop.NativeApplication.nativeApplication;
Autre solution, si le script
AIRAliases.js
a été importé, vous adoptez la forme plus courte suivante :
var app = air.NativeApplication.nativeApplication;
L’objet NativeApplication est uniquement accessible à partir du sandbox de l’application. Pour plus d’informations sur l'objet NativeApplication, voir
Utilisation des informations sur le moteur d’exécution d’AIR et les systèmes d’exploitation
.
Modèle d’URL JavaScript
L’exécution d’un code défini dans un modèle d’URL JavaScript (comme dans
href="javascript:alert('Test')"
) est bloquée au sein du sandbox de l’application. Aucune erreur n’est renvoyée.
|
|
|