JavaScript in AIR

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

AIR ha introdotto diverse modifiche nel comportamento tipico degli oggetti JavaScript comuni. Molte di queste modifiche vengono apportate per semplificare la scrittura di applicazioni sicure in AIR. Allo stesso tempo, queste differenze nel comportamento indicano che alcuni modelli di codifica e le applicazioni Web esistenti che li adottano non sempre possono essere eseguiti come previsto in AIR. Per informazioni sulla correzione di questo tipo di problemi, consultate Errori JavaScript relativi alla sicurezza da evitare .

Sandbox HTML

AIR colloca il contenuto in sandbox isolate in base all'origine del contenuto. Le regole della sandbox sono coerenti con il criterio della stessa origine implementato dalla maggior parte dei browser Web, nonché con le regole per le sandbox implementate da Adobe Flash Player. Inoltre, AIR fornisce un nuovo tipo di sandbox dell' applicazione per contenere e proteggere il contenuto dell'applicazione. Per ulteriori informazioni sui tipi di sandbox che è possibile incontrare quando si sviluppano applicazioni AIR, vedete Sandbox di sicurezza .

L'accesso all'ambiente di runtime e alle API AIR è disponibile solo per HTML e JavaScript in esecuzione nella sandbox dell'applicazione. Allo stesso tempo, tuttavia, la valutazione dinamica e l'esecuzione di JavaScript, nelle varie forme, per motivi di sicurezza è ampiamente limitata nella sandbox dell'applicazione. Queste restrizioni sono attive a prescindere se l'applicazione carichi effettivamente o meno le informazioni direttamente da un server. (Persino il contenuto dei file, le stringhe incollate e l'input diretto dell'utente possono essere inaffidabili).

L'origine del contenuto in una pagina determina la sandbox a cui è consegnata. Solo il contenuto caricato dalla directory dell'applicazione (la directory di installazione a cui fa riferimento lo schema URL app: ) viene collocato nella sandbox dell'applicazione. Il contenuto caricato dal file system viene collocato nella sandbox locale-con-filesystem oppure nella sandbox locale-attendibile : ciò consente l'accesso e l'interazione con il contenuto sul file system locale, ma non con il contenuto remoto. Il contenuto caricato dalla rete viene collocato in una sandbox remota che corrisponde al relativo dominio di origine.

Per consentire la libera interazione della pagina di un'applicazione con il contenuto di una sandbox remota, è possibile mappare la pagina allo stesso dominio del contenuto remoto. Ad esempio, se si scrive un'applicazione per la visualizzazione dei dati di mappa da un servizio Internet, la pagina dell'applicazione che consente di caricare e visualizzare il contenuto dal servizio potrebbe essere mappata sul dominio del servizio. Gli attributi per la mappatura delle pagine in un dominio e una sandbox remoti sono attributi nuovi aggiunti agli elementi HTML di frame e iframe.

Per consentire al contenuto di una sandbox non dell'applicazione di utilizzare in modo sicuro le funzionalità AIR, è possibile impostare un bridge sandbox principale. Per consentire al contenuto di un'applicazione di effettuare chiamate sicure a metodi e proprietà di accesso del contenuto in altre sandbox, è possibile impostare un bridge sandbox secondario. Per sicurezza qui si intende che il contenuto remoto non può ottenere inavvertitamente riferimenti ad oggetti, proprietà o metodi non esposti esplicitamente. Il bridge consente unicamente il passaggio di oggetti anonimi, funzioni e tipi di dati semplici. È tuttavia necessario evitare l'esposizione esplicita di funzioni potenzialmente pericolose. Se, ad esempio, è stata esposta un'interfaccia che consentiva al contenuto remoto di leggere e scrivere file in un punto qualsiasi del sistema di un utente, il contenuto remoto potrebbe aver ricevuto i mezzi per danneggiare in maniera considerevole gli utenti.

Funzione JavaScript eval()

L'utilizzo della funzione eval() nella sandbox di una applicazione è limitato a dopo che una pagina ha effettuato il caricamento. Sono consentiti alcuni impieghi in modo che i dati formattati con JSON possano essere analizzati in maniera sicura, ma qualsiasi valutazione che abbia come risultato istruzioni eseguibili genera un errore. Nella sezione Restrizioni relative al codice per il contenuto presente in diverse sandbox vengono descritti gli impieghi consentiti della funzione eval() .

Costruttori di funzioni

Nella sandbox dell'applicazione, i costruttori di funzioni possono essere utilizzati prima che il caricamento di una pagina sia terminato. Quando tutti i gestori dell'evento load sono terminati, non è possibile creare nuove funzioni.

Caricamento di script esterni

La pagine HTML nella sandbox dell'applicazione non possono utilizzare il tag script per caricare i file JavaScript dall'esterno della directory dell'applicazione. Per consentire a una pagina dell'applicazione di caricare uno script dall'esterno della directory dell'applicazione, è necessario che la pagina sia mappata a una sandbox non dell'applicazione.

Oggetto XMLHttpRequest

AIR fornisce un oggetto XMLHttpRequest (XHR) che le applicazioni possono utilizzare per effettuare richieste di dati. Nell'esempio seguente è illustrata una richiesta di dati semplice:

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); 

Contrariamente a un browser, AIR consente al contenuto in esecuzione nella sandbox di un'applicazione di richiedere i dati da un dominio qualsiasi. Il risultato di un XHR che contiene una stringa JSON può essere valutato negli oggetti dati a meno che i risultati non contengano anche codice eseguibile. Se nel risultato XHR sono presenti istruzioni eseguibili, viene generato un errore e il tentativo di valutazione non riesce.

Per impedire l'inserimento accidentale di codice da origini remote, XHR sincroni creati prima che sia terminato il caricamento di una pagina restituiscono un risultato vuoto. Dopo che una pagina è stata caricata, vengono sempre restituiti XHR asincroni.

Per impostazione predefinita, AIR blocca gli oggetti XMLHttpRequests tra i domini nelle sandbox non dell'applicazione. Una finestra principale della sandbox dell'applicazione può scegliere di consentire le richieste tra domini in un frame secondario che include il contenuto di una sandbox non dell'applicazione impostando allowCrossDomainXHR , un attributo aggiunto da AIR, su true nell'elemento contenitore frame o iframe:

<iframe id="mashup" 
    src="http://www.example.com/map.html" 
    allowCrossDomainXHR="true" 
</iframe>
Nota: se conviene, anche la classe URLStream può essere utilizzata per scaricare i dati.

Se si invia un oggetto XMLHttpRequest a un server remoto da un frame o un iframe che include contenuto dell'applicazione mappato a una sandbox remota, accertarsi che l'URL di mappatura non mascheri l'indirizzo server utilizzato nell'XHR. Si consideri ad esempio la seguente definizione iframe, che mappa il contenuto dell'applicazione in una sandbox remota per il dominio example.com:

<iframe id="mashup" 
    src="http://www.example.com/map.html" 
    documentRoot="app:/sandbox/" 
    sandboxRoot="http://www.example.com/" 
    allowCrossDomainXHR="true" 
</iframe>

Dal momento che l'attributo sandboxRoot rimappa l'URL principale dell'indirizzo www.example.com, tutte le richieste vengono caricate dalla directory dell'applicazione e non dal server remoto. Le richieste vengono rimappate sia che derivino dall'esplorazione della pagina che da un oggetto XMLHttpRequest.

Per evitare il blocco accidentale delle richieste di dati nel server remoto, mappare sandboxRoot a una sottodirectory dell'URL remoto anziché alla radice. Non è necessario che la directory esista. Ad esempio, per consentire il caricamento delle richieste a www.example.com dal server remoto anziché dalla directory dell'applicazione, cambiare l'iframe precedente nel seguente:

<iframe id="mashup" 
    src="http://www.example.com/map.html" 
    documentRoot="app:/sandbox/" 
    sandboxRoot="http://www.example.com/air/" 
    allowCrossDomainXHR="true" 
</iframe>

In questo caso, viene caricato a livello locale solo il contenuto della sottodirectory air .

Per ulteriori informazioni sulla mappatura di sandbox, vedete Elementi frame e iframe HTML e Sicurezza HTML in Adobe AIR .

Cookie

Nelle applicazioni AIR, solo il contenuto delle sandbox remote (caricato dalle origini http: e https:) può utilizzare i cookie (proprietà document.cookie ). Nella sandbox dell'applicazione, sono disponibili altri sistemi per l'archiviazione dei dati persistenti, comprese le classi EncryptedLocalStore, SharedObject e FileStream.

Oggetto Clipboard

L'API Clipboard di WebKit viene attivata mediante i seguenti eventi: copy (copia), cut (taglia) e paste (incolla). L'oggetto evento trasmesso in questi eventi fornisce accesso agli Appunti mediante la proprietà clipboardData . Utilizzare i seguenti metodi dell'oggetto clipboardData per leggere o scrivere dati degli Appunti:

Metodo

Descrizione

clearData(mimeType)

Cancella i dati degli Appunti. Impostare il parametro mimeType sul tipo MIME dei dati da cancellare.

getData(mimeType)

Richiama i dati degli Appunti. Questo metodo può essere chiamato solo in un gestore dell'evento paste . Impostare il parametro mimeType sul tipo MIME dei dati da restituire.

setData(mimeType, data)

Copia i dati negli Appunti. Impostate il parametro mimeType sul tipo di dati MIME.

Il codice JavaScript esterno alla sandbox dell'applicazione può accedere agli Appunti solo attraverso questi eventi. Tuttavia, il contenuto della sandbox dell'applicazione può accedere agli Appunti di sistema direttamente tramite la classe Clipboard AIR. Ad esempio, è possibile utilizzare la seguente istruzione per ottenere dati in formato testo sugli Appunti:

var clipping = air.Clipboard.generalClipboard.getData("text/plain", 
                                air.ClipboardTransferMode.ORIGINAL_ONLY);

I tipi di dati MIME validi sono:

Tipo MIME

Valore

Testo

"text/plain"

HTML

"text/html"

URL

"text/uri-list"

Bitmap

"image/x-vnd.adobe.air.bitmap"

Elenco file

"application/x-vnd.adobe.air.file-list"

Importante: solo il contenuto della sandbox dell'applicazione può accedere ai dati di un file presente negli Appunti. Se il contenuto non dell'applicazione tenta di accedere a un oggetto file dagli Appunti, viene generato un errore di protezione.

Per ulteriori informazioni sull'uso degli Appunti, vedete Copia e incolla e Using the Pasteboard from JavaScript (Apple Developer Center) (Utilizzo del modulo Pasteboard di JavaScript nel Centro per sviluppatori Apple).

Trascinamento della selezione

I movimenti di trascinamento della selezione all'interno e all'esterno di file HTML producono i seguenti eventi DOM: dragstart , drag , dragend , dragenter , dragover , dragleave e drop . L'oggetto evento trasmesso in questi eventi fornisce accesso ai dati trascinati mediante la proprietà dataTransfer . La proprietà dataTransfer fa riferimento a un oggetto che fornisce gli stessi metodi dell'oggetto clipboardData associato a un evento degli Appunti. Ad esempio, è possibile utilizzare la seguente funzione per ottenere dati in formato testo da un evento drop :

function onDrop(dragEvent){ 
    return dragEvent.dataTransfer.getData("text/plain",  
            air.ClipboardTransferMode.ORIGINAL_ONLY); 
}

L'oggetto dataTransfer dispone dei seguenti membri importanti:

Membro

Descrizione

clearData(mimeType)

Cancella i dati. Impostate il parametro mimeType sul tipo MIME della rappresentazione dei dati da cancellare.

getData(mimeType)

Richiama i dati trascinati. Questo metodo può essere chiamato solo in un gestore per l'evento drop . Impostate il parametro mimeType sul tipo MIME dei dati da richiamare.

setData(mimeType, data)

Imposta i dati da trascinare. Impostate il parametro mimeType sul tipo di dati MIME.

types

Un array di stringhe contenente i tipi MIME di tutte le rappresentazioni dei dati attualmente disponibili nell'oggetto dataTransfer .

effectsAllowed

Specifica se i dati trascinati possono essere copiati, spostati, collegati o possono subire una combinazione di qualche azione di cui sopra. Impostate la proprietà effectsAllowed nel gestore per l'evento dragstart .

dropEffect

Specifica quali degli effetti drop consentiti sono supportati da una destinazione di trascinamento. Impostate la proprietà dropEffect nel gestore per l'evento dragEnter . Durante il trascinamento della selezione, il cursore cambia aspetto, ad indicare l'effetto che risulterebbe dal rilascio del mouse. Se nessun effetto dropEffect è specificato, viene scelto un effetto della proprietà effectsAllowed . L'effetto di copia ha la priorità sull'effetto di spostamento, che a sua volta ha la priorità sull'effetto di collegamento. L'utente può modificare la priorità predefinita utilizzando la tastiera.

Per ulteriori informazioni sull'aggiunta di supporto per operazioni di trascinamento della selezione in un'applicazione AIR, consultate Trascinamento in AIR e Using the Drag-and-Drop from JavaScript (Apple Developer Center) (Utilizzo della funzione di trascinamento della selezione in JavaScript nel Centro per sviluppatori Apple).

Proprietà innerHTML e outerHTML

AIR pone limiti di sicurezza sull'uso delle proprietà innerHTML e outerHTML per il contenuto in esecuzione nella sandbox dell'applicazione. Prima dell'evento di caricamento della pagina, nonché durante l'esecuzione di qualsiasi gestore di eventi di carico, l'utilizzo delle proprietà innerHTML e outerHTML è illimitato. Tuttavia, dopo che la pagina è stata caricata, per aggiungere contenuto statico al documenti è possibile utilizzare solo le proprietà innerHTML o outerHTML . Qualsiasi istruzione nella stringa assegnata a innerHTML o outerHTML che restituisca codice eseguibile viene ignorata. Ad esempio, se si include un attributo di callback di un evento nella definizione di un elemento, il listener di eventi non viene aggiunto. Analogamente, i tag <script> incorporati non vengono valutati. Per ulteriori informazioni, vedete Sicurezza HTML in Adobe AIR .

Metodi Document.write() e Document.writeln()

L'utilizzo dei metodi write() e writeln() non è limitato nella sandbox dell'applicazione prima dell'evento load della pagina. Tuttavia, dopo che la pagina è stata caricata, la chiamata a uno di questi metodi non determina la cancellazione della pagina o la creazione di una nuova pagina. Nella sandbox non dell'applicazione, come nella maggior parte dei browser Web, la chiamata di document.write() o writeln() dopo che è stato effettuato il caricamento di una pagina cancella la pagina corrente e ne apre una nuova, vuota.

Proprietà Document.designMode

Impostate la proprietà document.designMode su un valore on per rendere modificabili tutti gli elementi del documento. Il supporto editor incorporato include modifica del testo, copia, incolla e trascinamento della selezione. L'impostazione di designMode su on equivale ad impostare la proprietà contentEditable dell'elemento body su true . Per definire quali sezioni sono modificabili, è possibile utilizzare la proprietà contentEditable sulla maggior parte degli elementi HTML. Per ulteriori informazioni, consultate Attributo contentEditable di HTML .

unload, eventi (per oggetti body e frameset)

Nel tag di primo livello frameset o body di una finestra, inclusa la finestra principale dell'applicazione, non utilizzate l'evento unload per rispondere alla chiusura della finestra (o dell'applicazione). Utilizzate al suo posto l'evento exiting dell'oggetto NativeApplication per rilevare quando un'applicazione è in fase di chiusura. In alternativa, utilizzate l'evento closing dell'oggetto NativeWindow, che consente di rilevare quando una finestra è in fase di chiusura. Ad esempio, il seguente codice JavaScript consente di visualizzare un messaggio di saluto ( "Goodbye." ) quando l'utente chiude l'applicazione:

var app = air.NativeApplication.nativeApplication; 
app.addEventListener(air.Event.EXITING, closeHandler); 
function closeHandler(event) 
{ 
    alert("Goodbye."); 
}

Tuttavia, gli script possono rispondere all'evento unload causato dall'esplorazione del contenuto di un frame, un iframe o una finestra di primo livello.

Nota: queste limitazioni potrebbero essere rimosse in una versione successiva di Adobe AIR.

Oggetto Window di JavaScript

L'oggetto Window resta l'oggetto globale nel contesto di esecuzione di JavaScript. Nella sandbox dell'applicazione, AIR aggiunge nuove proprietà all'oggetto Window di JavaScript per fornire accesso alle classi incorporate di AIR nonché ad importanti oggetti host. Inoltre, alcuni metodi e proprietà hanno un comportamento diverso a seconda se si trovano o meno nella sandbox dell'applicazione.

Proprietà Window.runtime
La proprietà runtime consente di effettuare istanze e utilizzare le classi di runtime incorporate dalla sandbox dell'applicazione. Queste classi includono le API AIR e Flash Player, ma non, ad esempio, la struttura Flex. Ad esempio, la seguente istruzione consente di creare un oggetto file AIR:
var preferencesFile = new window.runtime.flash.filesystem.File();

Il file AIRAliases.js , fornito in AIR SDK, contiene definizioni di alias che consentono di abbreviare tali riferimenti. Quando AIRAliases.js viene importato in una pagina, ad esempio, è possibile creare un oggetto File con la seguente istruzione:

var preferencesFile = new air.File();

La proprietà window.runtime è definita solo per il contenuto all'interno della sandbox dell'applicazione e solo per il documento principale di una pagina con frame o iframe.

Consultate Uso del file AIRAliases.js .

Proprietà Window.nativeWindow
La proprietà nativeWindow fornisce un riferimento all'oggetto native window sottostante. Mediante questa proprietà è possibile creare script di funzioni della finestra e di proprietà quali posizione dello schermo, dimensione e visibilità. Consente inoltre di gestire eventi quali chiusura, ridimensionamento e spostamento. L'istruzione seguente, ad esempio, consente la chiusura della finestra:
window.nativeWindow.close();
Nota: le funzionalità di controllo della finestra fornite dall'oggetto NativeWindow si sovrappongono alle funzionalità fornite dall'oggetto Window di JavaScript. In tali casi è possibile utilizzare il metodo che si ritiene più conveniente.

La proprietà window.nativeWindow è definita solo per il contenuto all'interno della sandbox dell'applicazione e solo per il documento principale di una pagina con frame o iframe.

Proprietà Window.htmlLoader
La proprietà htmlLoader offre un riferimento all'oggetto HTMLLoader AIR che include il contenuto HTML. Grazie a questa proprietà è possibile creare script per l'aspetto e il comportamento dell'ambiente HTML. Ad esempio, è possibile utilizzare la proprietà htmlLoader.paintsDefaultBackground per determinare se il controllo dipinge uno sfondo bianco predefinito:
window.htmlLoader.paintsDefaultBackground = false;
Nota: lo stesso oggetto HTMLLoader dispone di una proprietà window che fa riferimento all'oggetto Window di JavaScript del contenuto HTML che include. È possibile utilizzare questa proprietà per accedere all'ambiente JavaScript attraverso un riferimento all'HTMLLoader contenitore.

La proprietà window.htmlLoader è definita solo per il contenuto all'interno della sandbox dell'applicazione e solo per il documento principale di una pagina con frame o iframe.

Proprietà Window.parentSandboxBridge e Window.childSandboxBridge
Le proprietà parentSandboxBridge e childSandboxBridge consentono di definire un'interfaccia tra un frame principale e uno secondario. Per ulteriori informazioni, consultate Scambio di script per il contenuto presente in sandbox di sicurezza diverse .

Funzioni Window.setTimeout() e Window.setInterval()
AIR pone limiti di sicurezza sull'uso delle funzioni setTimeout() e setInterval() nella sandbox dell'applicazione. Non è possibile definire il codice da eseguire come stringa quando si effettua la chiamata a setTimeout() o setInterval() . È necessario utilizzare un riferimento a una funzione. Per ulteriori informazioni, consultate setTimeout() e setInterval() .

Funzione Window.open()
Se chiamato da un codice in esecuzione in una sandbox non dell'applicazione, il metodo open() apre una finestra solo quando viene chiamato come risultato di un'interazione utente (ad esempio, un clic del mouse o la pressione di un tasto sulla tastiera). Il titolo della finestra, inoltre, è preceduto da un prefisso con il titolo dell'applicazione, per impedire che le finestre aperte dal contenuto remoto "impersonino" finestre aperte dall'applicazione). Per ulteriori informazioni, consultate Restrizioni relative alla chiamata al metodo JavaScript window.open() .

Oggetto air.NativeApplication

L'oggetto NativeApplication fornisce informazioni sullo stato dell'applicazione, distribuisce diversi importanti eventi a livello di applicazione e fornisce funzioni utili per il controllo del comportamento delle applicazioni. Viene creata automaticamente una singola istanza dell'oggetto NativeApplication, e ad essa è possibile accedere tramite la proprietà NativeApplication.nativeApplication definita dalla classe.

Per accedere all'oggetto dal codice JavaScript è possibile utilizzare quanto segue:

var app = window.runtime.flash.desktop.NativeApplication.nativeApplication;

In alternativa, se lo script AIRAliases.js è stato importato, è possibile scegliere la forma abbreviata:

var app = air.NativeApplication.nativeApplication;

All'oggetto NativeApplication è possibile accedere solo dall'interno della sandbox dell'applicazione. Per ulteriori informazioni sull'oggetto NativeApplication, vedete Uso delle informazioni di runtime AIR e del sistema operativo .

Lo schema URL di JavaScript

L'esecuzione di codice definito in uno schema URL di JavaScript (come in href="javascript:alert('Test')" ) viene bloccata all'interno della sandbox dell'applicazione. Non viene generato alcun errore.