JavaScript no AIR

Flash Player 9 e posterior, Adobe AIR 1.0 e posterior

O AIR faz várias alterações no comportamento típico de objetos JavaScript comuns. Várias dessas alterações são feitas para tornar fácil escrever aplicativos seguros no AIR. Ao mesmo tempo, essas diferenças em comportamento significam que alguns padrões de codificação JavaScript comuns, e aplicativos Web existentes usando esses padrões, nem sempre podem executar conforme esperado no AIR. Para obter informações sobre como corrigir esses tipos de problemas, consulte Como evitar erros JavaScript relacionados à segurança .

Caixas de proteção HTML

O AIR coloca conteúdo em caixas de proteção isoladas de acordo com a origem do conteúdo. As regras da caixa de proteção são consistentes com a política de mesma origem implementada pela maioria dos navegadores da Web, bem como as regras para caixas de proteção implementadas pelo Adobe Flash Player. Além disso, o AIR fornece um novo tipo de caixa de proteção do aplicativo para conter e proteger conteúdo do aplicativo. Consulte Caixas de proteção de segurança para obter mais informações sobre os tipos de caixas de proteção que você pode encontrar ao desenvolver aplicativos AIR.

O acesso ao ambiente de tempo de execução e às APIs do AIR está disponível apenas para HTML e JavaScript em execução na caixa de proteção do aplicativo. Ao mesmo tempo, no entanto, a execução e avaliação dinâmica de JavaScript, em suas várias formas, são amplamente restritas na caixa de proteção do aplicativo por razões de segurança. Essas restrições são adequadas quer seu aplicativo realmente carregue ou não informações diretamente de um servidor. (Até mesmo conteúdo de arquivo, sequências de caracteres coladas e entrada do usuário direta podem ser incertos.)

A origem do conteúdo em uma página determina a caixa de proteção à qual ele é consignado. Apenas o conteúdo carregado do diretório do aplicativo (o diretório de instalação referenciado pelo app: esquema de URL) é colocado na caixa de proteção do aplicativo. O conteúdo carregado do sistema de arquivos é colocado na caixa de proteção local com sistema de arquivos ou confiável local , que permite acesso e interação com conteúdo no sistema de arquivos local, mas não conteúdo remoto. O conteúdo carregado da rede é colocado em uma caixa de proteção remota correspondente ao seu domínio de origem.

Para permitir que uma página de aplicativo interaja livremente com o conteúdo em uma caixa de proteção remota, a página pode ser mapeada para o mesmo domínio do conteúdo remoto. Por exemplo, se você escreve um aplicativo que exibe dados de mapas de um serviço de Internet, a página do seu aplicativo que carrega e exibe conteúdo do serviço poderia ser mapeada para o domínio de serviço. Os atributos para mapear páginas em um domínio e uma caixa de proteção remota são novos atributos adicionados aos elementos HTML frame e iframe.

Para permitir conteúdo em uma caixa de proteção que não seja de aplicativo para usar com segurança recursos do AIR, você pode configurar uma ponte de caixa de proteção pai. Para permitir que o conteúdo de aplicativo chame com segurança métodos e acesse propriedades de conteúdo em outras caixas de proteção, você pode configurar uma ponte de caixa de proteção filha. Segurança aqui significa que o conteúdo remoto não pode obter acidentalmente referências a objetos, propriedades ou métodos que não são expostos explicitamente. Apenas tipos de dados simples, funções e objetos anônimos podem ser transmitidos pela ponte. No entanto, você ainda deve evitar expor explicitamente funções potencialmente perigosas. Se, por exemplo, você expôs uma interface que permitiu ao conteúdo remoto ler e escrever arquivos em qualquer lugar no sistema de um usuário, você pode estar fornecendo ao conteúdo remoto o meio para fazer um dano considerável aos seus usuários.

Função eval() do JavaScript

O uso da função eval() é restrito à caixa de proteção do aplicativo depois que o carregamento de uma página tiver sido concluído. Alguns usos são permitidos para que dados formatados por JSON possam ser analisados com segurança, mas qualquer avaliação que resulte em instruções executáveis terá como consequência um erro. O capítulo Restrições de código de conteúdo em caixas de proteção distintas descreve os usos permitidos da função eval() .

Construtores de funções

Na caixa de proteção do aplicativo, os construtores de funções podem ser usados antes que o carregamento de uma página tenha sido concluído. Após todos os manipuladores de eventos load da página terem sido concluídos, novas funções não podem ser criadas.

Carregamento de scripts externos

As páginas HTML na caixa de proteção do aplicativo não podem usar a tag de script para carregar arquivos de JavaScript de fora do diretório do aplicativo. Para uma página no seu aplicativo carregar um script de fora do diretório do aplicativo, a página deve ser mapeada para uma caixa de proteção que não seja de aplicativo.

O objeto XMLHttpRequest

O AIR fornece um objeto XMLHttpRequest (XHR) que os aplicativos podem usar para fazer solicitações de dados. O exemplo a seguir ilustra uma solicitação de dados simples:

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

Em contraste com um navegador, o AIR permite que o conteúdo em execução na caixa de proteção do aplicativo solicite dados de qualquer domínio. O resultado de um XHR que contém uma sequência de caracteres JSON pode ser avaliado em objetos de dados, a menos que o resultado também contenha código executável. Se instruções executáveis estão presentes no resultado de XHR, um erro é lançado e a tentativa de avaliação falha.

Para impedir a injeção acidental de código de fontes remotas, os XHRs síncronos retornam um resultado vazio se feito antes que o carregamento de uma página seja concluído. Os XHRs assíncronos sempre são retornados após o carregamento de uma página.

Por padrão, o AIR bloqueia XMLHttpRequests entre vários domínios em caixas de proteção de não aplicativos. Uma janela pai na caixa de proteção do aplicativo pode optar por permitir solicitações entre domínios em um frame filho com conteúdo em uma caixa de proteção que não seja de aplicativo definindo allowCrossDomainXHR , um atributo adicionado pelo AIR, como true no elemento frame ou iframe contido:

<iframe id="mashup" 
    src="http://www.example.com/map.html" 
    allowCrossDomainXHR="true" 
</iframe>
Nota: Quando conveniente, a classe URLStream do AIR também pode ser usada para fazer o download de dados.

Se você despachar um XMLHttpRequest para um servidor remoto de um frame ou iframe contendo conteúdo de aplicativo que tenha sido mapeado para uma caixa de proteção remota, verifique se a URL de mapeamento não mascara o endereço do servidor usado no XHR. Por exemplo, considere a seguinte definição de iframe, que mapeia conteúdo de aplicativo em uma caixa de proteção remota para o domínio example.com:

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

Como o atributo sandboxRoot remapeia a URL raiz do endereço www.example.com, todas as solicitações são carregadas do diretório do aplicativo, e não do servidor remoto. As solicitações são remapeadas derivem elas de navegação de página ou de um XMLHttpRequest.

Para evitar bloquear solicitações de dados acidentalmente para o seu servidor remoto, mapeie sandboxRoot para um subdiretório da URL remota, e não da raiz. O diretório não precisa existir. Por exemplo, para permitir solicitações ao www.example.com para ser carregado do servidor remoto, e não do diretório do aplicativo, altere o iframe anterior para o seguinte:

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

Nesse caso, apenas conteúdo no subdiretório air é carregado localmente.

Para obter mais informações sobre o mapeamento de caixa de proteção, consulte Elementos HTML frame e iframe e Segurança HTML no Adobe AIR .

Cookies

Em aplicativos AIR, apenas o conteúdo em caixas de proteção remotas (conteúdo carregado de fontes http: e https:) pode usar cookies (a propriedade document.cookie ). Na caixa de proteção do aplicativo, há outras formas para armazenar os dados persistentes, incluindo as classes EncryptedLocalStore, SharedObject e FileStream.

O objeto Clipboard

A API Clipboard do WebKit é conduzida com os seguintes eventos: copy , cut e paste . O objeto event transmitido nesses eventos fornece acesso à área de transferência pela propriedade clipboardData . Use os seguintes métodos do objeto clipboardData para ler ou escrever dados da área de transferência:

Método

Descrição

clearData(mimeType)

Limpa os dados da área de transferência. Defina o parâmetro mimeType para o tipo MIME dos dados a apagar.

getData(mimeType)

Obtém os dados da área de transferência. Esse método pode ser chamado apenas em um manipulador para o evento paste . Defina o parâmetro mimeType para o tipo MIME dos dados a retornar.

setData(mimeType, data)

Copia dados para a área de transferência. Defina o parâmetro mimeType para o tipo MIME dos dados.

O código JavaScript fora da caixa de proteção do aplicativo pode acessar apenas a área de transferência por esses eventos. No entanto, o conteúdo na caixa de proteção do aplicativo pode acessar a área de transferência do sistema diretamente usando a classe Clipboard do AIR. Por exemplo, você poderia usar a seguinte instrução para obter dados do formato do texto na área de transferência:

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

Os tipos MIME de dados válidos são:

Tipo MIME

Valor

Texto

"text/plain"

HTML

"text/html"

URL

"text/uri-list"

Bitmap

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

Lista de arquivos

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

Importante: Apenas conteúdo na caixa de proteção do aplicativo pode acessar dados de arquivos presentes na área de transferência. Se um conteúdo que não seja de aplicativo tentar acessar um objeto de arquivo da área de transferência, será lançado um erro de segurança.

Para obter mais informações sobre o uso da área de transferência, consulte Copiar e colar e Utilização da área de trabalho de JavaScript (Centro de desenvolvedores da Apple) .

Arrastar e soltar

Gestos de arrastar e soltar para dentro e para fora do HTML produzem os seguintes eventos DOM: dragstart , drag , dragend , dragenter , dragover , dragleave e drop . O objeto event transmitido nesses eventos fornece acesso aos dados arrastados pela propriedade dataTransfer . A propriedade dataTransfer faz referência a um objeto que fornece os mesmos métodos do objeto clipboardData associado a um evento clipboard. Por exemplo, você poderia usar a seguinte função para obter dados do formato de um evento drop :

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

O objeto dataTransfer possui os seguintes membros importantes:

Membro

Descrição

clearData(mimeType)

Limpa os dados. Defina o parâmetro mimeType para o tipo MIME da representação de dados para apagar.

getData(mimeType)

Obtém os dados arrastados. Esse método pode ser chamado apenas em um manipulador para o evento drop . Defina o parâmetro mimeType para o tipo MIME dos dados a obter.

setData(mimeType, data)

Defina os dados a serem arrastados. Defina o parâmetro mimeType para o tipo MIME dos dados.

tipos

Uma matriz de sequências de caracteres contendo os tipos MIME de todas as representações de dados disponíveis no momento no objeto dataTransfer .

effectsAllowed

Especifica se os dados que estão sendo arrastados podem ser copiados, movidos, vinculados ou alguma combinação disso. Defina a propriedade effectsAllowed no manipulador para o evento dragstart .

dropEffect

Especifica quais dos efeitos drop permitidos são suportados por um drag target. Defina a propriedade dropEffect no manipulador para o evento dragEnter . Durante a ação de arrastar, o cursor muda para indicar que efeito ocorreria se o usuário soltasse o mouse. Se nenhum dropEffect for especificado, um efeito da propriedade effectsAllowed será escolhido. O efeito de copiar tem prioridade sobre o efeito de mover, que por si só tem prioridade sobre o efeito de vincular. O usuário pode modificar a prioridade padrão usando o teclado.

Para obter mais informações sobre como adicionar suporte para arrastar e soltar a um aplicativo do AIR, consulte Arrastar e soltar no AIR e Utilização de arrastar e soltar de JavaScript (Centro de desenvolvedores da Apple) .

Propriedades innerHTML e outerHTML

O AIR coloca restrições de segurança sobre o uso das propriedades innerHTML e outerHTML para conteúdo em execução na caixa de proteção do aplicativo. Antes do evento de carregamento da página, bem como durante a execução de qualquer manipulador de evento de carregamento, o uso das propriedades innerHTML e outerHTML é irrestrito. No entanto, depois que a página é carregada, você pode apenas usar as propriedades innerHTML ou outerHTML para adicionar conteúdo estático ao documento. Qualquer instrução na sequência de caracteres atribuída a innerHTML ou outerHTML avaliada como código executável é ignorada. Por exemplo, se você incluir um atributo de retorno de evento em uma definição de elemento, o ouvinte de eventos não será adicionado. Da mesma forma, tags <script> incorporadas não são avaliadas. Para obter mais informações, consulte Segurança HTML no Adobe AIR .

Métodos Document.write() e Document.writeln()

O uso dos métodos write() e writeln() não é restrito à caixa de proteção do aplicativo antes do evento load da página. No entanto, depois que a página é carregada, chamar um desses métodos não limpa a página ou cria uma nova. Em uma caixa de proteção que não seja de aplicativo, como na maioria dos navegadores da Web, chamar document.write() ou writeln() , após a conclusão do carregamento de uma página, limpa a página atual e abre uma nova em branco.

Propriedade Document.designMode

Defina a propriedade document.designMode para um valor de on para tornar todos os elementos do documento editáveis. O suporte a editor incorporado inclui editar texto, copiar, colar e arrastar e soltar. Definir designMode como on é equivalente a definir a propriedade contentEditable do elemento body como true . Você pode usar a propriedade contentEditable na maioria dos elementos HTML para definir que seções de um documento são editáveis. Consulte Atributo contentEditable HTML para obter informações adicionais.

Eventos unload (para objetos body e frameset)

Na tag de nível superior frameset ou body de uma janela (incluindo a janela principal do aplicativo), não use o evento unload para responder à janela (ou aplicativo) que está sendo fechada. Em vez disso, use o evento exiting do objeto NativeApplication (para detectar quando um aplicativo está sendo fechando). Em vez disso, use o evento exiting do objeto NativeWindow (para detectar quando um aplicativo está sendo fechado). Por exemplo, o seguinte código JavaScript exibe uma mensagem ( "Goodbye." ) quando o usuário fecha o aplicativo:

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

No entanto, scripts podem responder com êxito ao evento unload causado pela navegação de um conteúdo frame, iframe ou window de nível superior.

Nota: Essas limitações podem ser removidas em uma versão futura do Adobe AIR.

Objeto Window do JavaScript

O objeto Window permanece o objeto global no contexto de execução do JavaScript. Na caixa de proteção do aplicativo, o AIR adiciona novas propriedades ao objeto Window do JavaScript para fornecer acesso às classes incorporadas do AIR, bem como importantes objetos de host. Além disso, alguns métodos e propriedades se comportam de modo diferente dependendo se estão ou não na caixa de proteção do aplicativo.

Propriedade Window.runtime
A propriedade runtime permite que você instancie e use classes runtime incorporadas da caixa de proteção do aplicativo. Essas classes incluem APIs do AIR e do Flash Player (mas não, por exemplo, a estrutura do Flex). Por exemplo, a seguinte instrução cria um objeto de arquivo do AIR:
var preferencesFile = new window.runtime.flash.filesystem.File();

O arquivo AIRAliases.js , fornecido no SDK do AIR, contém definições de aliases que permitem a você encurtar tais referências. Por exemplo, quando AIRAliases.js é importado em uma página, um objeto File pode ser criado com a seguinte instrução:

var preferencesFile = new air.File();

A propriedade window.runtime somente é definida para conteúdo dentro da caixa de proteção do aplicativo e apenas para o documento pai de uma página com frames ou iframes.

Consulte Uso do arquivo AIRAliases.js .

Propriedade Window.nativeWindow
A propriedade nativeWindow fornece uma referência ao objeto de janela nativa subjacente. Com essa propriedade, você pode fazer o script de funções e propriedades de janela, como posição da tela, tamanho e visibilidade e manipular eventos de janela, como fechar, redimensionar e mover. Por exemplo, a seguinte instrução fecha a janela:
window.nativeWindow.close();
Nota: Os recursos de controle da janela fornecidos pelo objeto NativeWindow sobrepõem os recursos fornecidos pelo objeto Window do JavaScript. Em tais casos, você pode usar qualquer método que considerar mais conveniente.

A propriedade window.nativeWindow somente é definida para conteúdo dentro da caixa de proteção do aplicativo e apenas para o documento pai de uma página com frames ou iframes.

Propriedade Window.htmlLoader
A propriedade htmlLoader fornece uma referência ao objeto AIR HTMLLoader que contém o conteúdo HTML. Com essa propriedade, você pode fazer o script da aparência e do comportamento do ambiente HTML. Por exemplo, você pode usar a propriedade htmlLoader.paintsDefaultBackground para determinar se o controle pinta um plano de fundo branco padrão:
window.htmlLoader.paintsDefaultBackground = false;
Nota: O objeto HTMLLoader por si só possui uma propriedade window , que faz referência ao objeto Window do JavaScript do conteúdo HTML contido nele. Você pode usar essa propriedade para acessar o ambiente JavaScript por uma referência ao HTMLLoader contido.

A propriedade window.htmlLoader somente é definida para conteúdo dentro da caixa de proteção do aplicativo e apenas para o documento pai de uma página com frames ou iframes.

Propriedades Window.parentSandboxBridge e Window.childSandboxBridge
As propriedades parentSandboxBridge e childSandboxBridge permitem que você defina uma interface entre um frame filho e um pai. Para obter mais informações, consulte Conteúdo cross-scripting em caixas de proteção de segurança distintas .

Funções Window.setTimeout() e Window.setInterval()
O AIR coloca restrições de segurança sobre o uso das funções setTimeout() e setInterval() na caixa de proteção do aplicativo. Não é possível definir o código a ser executado como uma sequência de caracteres ao chamar setTimeout() ou setInterval() . É necessário usar uma referência de função. Para obter mais informações, consulte setTimeout() e setInterval() .

Função Window.open()
Quando chamado por código em execução em uma caixa de proteção que não seja de aplicativo, o método open() abrirá somente uma janela quando chamado como resultado da interação do usuário (como um clique do mouse ou pressionamento de tecla). Além disso, o título da janela é prefixado com o título do aplicativo (para impedir que janelas sejam abertas por conteúdo remoto personifiquem janelas abertas pelo aplicativo). Para obter mais informações, consulte o capítulo Restrições na chamada do método window.open() de JavaScript .

Objeto air.NativeApplication

O objeto NativeApplication fornece informações sobre o estado do aplicativo, despacha vários eventos de nível de aplicativo importantes e fornece funções úteis para controlar o comportamento do aplicativo. Uma única instância do objeto NativeApplication é criada automaticamente e pode ser acessada pela propriedade NativeApplication.nativeApplication definida pela classe.

Para acessar o objeto do código JavaScript, você poderia usar:

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

Ou, se o script AIRAliases.js tiver sido importado, você poderia usar a forma mais curta:

var app = air.NativeApplication.nativeApplication;

O objeto NativeApplication pode apenas ser acessado de dentro da caixa de proteção do aplicativo. Para obter mais informações sobre o objeto NativeApplication, consulte Trabalho com informações de tempo de execução do AIR e de sistema operacional .

O esquema de URL JavaScript

A execução do código definida em um esquema de URL de JavaScript (como em href="javascript:alert('Test')" ) é bloqueada na caixa de proteção do aplicativo. Nenhum erro é lançado.