AIR 中的 JavaScriptFlash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 AIR 对通用 JavaScript 对象的典型行为进行了若干更改。其中,很多更改都是为了在 AIR 中更方便地编写安全应用程序。同时,这些行为差异表示某些通用 JavaScript 编码模式和使用这些模式的现有 Web 应用程序在 AIR 中可能始终不会按预期方式执行。有关更正这些问题类型的信息,请参阅避免与安全相关的 JavaScript 错误。 HTML 沙箱AIR 根据内容的原始位置将该内容放置到隔离沙箱中。沙箱规则与大多数 Web 浏览器实现的具有相同原始位置的策略一致,并且与 Adobe Flash Player 实现的沙箱规则一致。此外,AIR 还提供了一个包含并保护应用程序内容的新应用程序 沙箱类型。有关在开发 AIR 应用程序时可能遇到的沙箱类型的详细信息,请参阅安全沙箱。 只有在应用程序沙箱中运行的 HTML 和 JavaScript 才能访问运行时环境和 AIR API。但同时,出于安全原因,动态计算和执行各种形式的 JavaScript 在应用程序沙箱内大幅受限。无论您的应用程序实际上是否从服务器直接加载信息,这些限制都将发挥作用。(即使是文件内容、粘贴的字符串和直接用户输入也可能不可靠。) 页内容的原始位置确定要将该内容放置到哪个沙箱。只能将从应用程序目录(app: URL 方案引用的安装目录)加载的内容放置到应用程序沙箱中。从文件系统加载的内容则放置到与本地文件系统内容交互的 沙箱或受信任的本地 沙箱中,以便访问本地文件系统上的内容(而不是远程内容),并与其进行交互。从网络加载的内容则放置到与其原始域对应的远程沙箱中。 若要使应用程序页与远程沙箱中的内容自由交互,则可以将该页映射到远程内容所在的相同域中。例如,如果编写显示 Internet 服务的映射数据的应用程序,则可以将加载和显示该服务内容的应用程序页映射到该服务域中。用于将页映射到远程沙箱和域的属性是 frame 和 iframe HTML 元素的新增属性。 若要使非应用程序沙箱中的内容安全地使用 AIR 功能,则可以设置父沙箱桥。若要使应用程序内容安全地调用其他沙箱中的内容的方法并访问其属性,则可以设置子沙箱桥。此处所述的安全性意味着远程内容不能意外获取对未显式公开的对象、属性或方法的引用。通过沙箱桥只能传递简单数据类型、函数和匿名对象。但是,您仍然必须避免显式公开潜在的危险函数。例如,如果公开的接口允许远程内容读取或写入用户系统中任意位置的文件,则可能会使远程内容严重危害用户。 JavaScript eval() 函数完成加载页之后,将在应用程序沙箱中限制使用 eval() 函数。在某些情况下允许使用该函数,以便可以安全地分析 JSON 格式数据,但是,生成可执行语句的任何计算将生成错误。对不同沙箱中的内容的代码限制介绍了允许使用 eval() 函数的情况。 加载外部脚本应用程序沙箱中的 HTML 页无法使用 script 标签从应用程序目录外部加载 JavaScript 文件。为使应用程序中的页能够从应用程序目录外部加载脚本,必须将该页映射到非应用程序沙箱。 XMLHttpRequest 对象AIR 提供了应用程序可用于执行数据请求的 XMLHttpRequest (XHR) 对象。下面的示例演示简单数据请求: 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); 与浏览器不同,AIR 允许在应用程序沙箱中运行的内容请求任何域中的数据。对于包含 JSON 字符串的 XHR 结果,除非该结果还包含可执行代码,否则可以计算出该结果的数据对象。如果 XHR 结果中存在可执行语句,则会引发错误,且计算尝试失败。 若要防止从远程源意外注入代码,在完成加载页之前执行同步 XHR 时将返回空结果。异步 XHR 将始终在加载页之后返回。 默认情况下,AIR 阻止在非应用程序沙箱中执行跨域 XMLHttpRequest。应用程序沙箱中的父窗口可以选择在包含非应用程序沙箱内容的子 frame 中允许跨域请求,方法是在包含非应用程序沙箱内容的 frame 或 iframe 元素中将 AIR 添加的 allowCrossDomainXHR 属性设置为 true: <iframe id="mashup" src="http://www.example.com/map.html" allowCrossDomainXHR="true" </iframe> 注: 还可以根据需要使用 AIR URLStream 类下载数据。
如果从包含已映射到远程沙箱的应用程序内容的 frame 或 iframe 对远程服务器调度 XMLHttpRequest,请确保映射 URL 不会遮蔽在 XHR 中使用的服务器地址。例如,请考虑以下 iframe 定义,该定义将应用程序内容映射到 example.com 域所对应的远程沙箱: <iframe id="mashup" src="http://www.example.com/map.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/" allowCrossDomainXHR="true" </iframe> 由于 sandboxRoot 属性重新映射 www.example.com 地址的根 URL,因此所有请求都将从应用程序目录加载,而不是从远程服务器加载。无论请求是派生自页导航还是 XMLHttpRequest,都将重新映射这些请求。 若要避免意外阻止对远程服务器的数据请求,请将 sandboxRoot 映射到远程 URL 的子目录,而不是根目录。该目录不一定存在。例如,若要允许从远程服务器加载对 www.example.com 的请求,而不是从应用程序目录加载,请将上面的 iframe 更改为以下内容: <iframe id="mashup" src="http://www.example.com/map.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/" allowCrossDomainXHR="true" </iframe> 在本例中,仅在本地加载 air 子目录中的内容。 有关沙箱映射的详细信息,请参阅 HTML frame 和 iframe 元素以及 Adobe AIR 中的 HTML 安全性。 Cookie在 AIR 应用程序中,只有远程沙箱中的内容(从 http: 和 https: 源加载的内容)才能使用 cookie(即 document.cookie 属性)。在应用程序沙箱中,还提供了存储永久性数据的其他方法,包括 EncryptedLocalStore、SharedObject 和 FileStream 类。 Clipboard 对象WebKit Clipboard API 由以下事件驱动:copy、cut 和 paste。在这些事件中传递的事件对象通过 clipboardData 属性提供对剪贴板的访问。使用 clipboardData 对象的以下方法可以读取或写入剪贴板数据:
应用程序沙箱外部的 JavaScript 代码只能通过上述事件访问剪贴板。但是,应用程序沙箱中的内容可以使用 AIR Clipboard 类直接访问系统剪贴板。例如,您可以使用以下语句获取剪贴板上的文本格式数据: var clipping = air.Clipboard.generalClipboard.getData("text/plain", air.ClipboardTransferMode.ORIGINAL_ONLY); 有效的数据 MIME 类型为:
重要说明: 只有应用程序沙箱中的内容才能访问剪贴板上的文件数据。如果非应用程序内容尝试访问剪贴板上的文件对象,则会引发安全错误。
有关使用剪贴板的详细信息,请参阅复制和粘贴以及 Using the Pasteboard from JavaScript(Apple 开发人员中心)。 拖放进出 HTML 的拖放动作生成下列 DOM 事件:dragstart、drag、dragend、dragenter、dragover、dragleave 和 drop。在这些事件中传递的事件对象通过 dataTransfer 属性提供对被拖动数据的访问。dataTransfer 属性引用的对象提供与剪贴板事件关联的 clipboardData 对象相同的方法。例如,您可以使用以下函数获取 drop 事件中的文本格式数据: function onDrop(dragEvent){ return dragEvent.dataTransfer.getData("text/plain", air.ClipboardTransferMode.ORIGINAL_ONLY); } dataTransfer 对象包含下列重要成员:
有关向 AIR 应用程序添加拖放支持的详细信息,请参阅AIR 中的拖放和 Using the Drag-and-Drop from JavaScript(Apple 开发人员中心)。 innerHTML 和 outerHTML 属性对于在应用程序沙箱中运行的内容,AIR 会对 innerHTML 和 outerHTML 属性的使用施加一些安全限制。在执行页 load 事件之前以及在执行任何 load 事件处理函数期间,innerHTML 和 outerHTML 属性的使用不受限制。但是,一旦完成页加载,则只能使用 innerHTML 或 outerHTML 属性向文档添加静态内容。分配给 innerHTML 或 outerHTML 的字符串中计算结果为可执行代码的任何语句都将被忽略。例如,如果在元素定义中包含事件回调属性,则不会添加事件侦听器。同样,不会计算嵌入的 <script> 标签。有关详细信息,请参阅 Adobe AIR 中的 HTML 安全性。 Document.write() 和 Document.writeln() 方法在执行页的 load 事件之前,可以在应用程序沙箱中不受限制地使用 write() 和 writeln() 方法。但是,一旦完成页加载,调用上述任一方法将不会清除页或创建新页。在非应用程序沙箱中,在完成页加载之后调用 document.write() 或 writeln() 将清除当前页或打开一个新的空白页,这与在大多数 Web 浏览器中相同。 Document.designMode 属性将 document.designMode 属性设置为值 on 可以编辑文档中的所有元素。内置编辑器支持包括文本编辑、复制、粘贴和拖放。将 designMode 设置为 on 等效于将 body 元素的 contentEditable 属性设置为 true。您可以对大多数 HTML 元素使用 contentEditable 属性,以便定义可以编辑文档的哪些部分。有关其他信息,请参阅HTML contentEditable 属性。 unload 事件(对于 body 和 frameset 对象)在窗口(包括应用程序主窗口)的顶级 frameset 或 body 标签中,切勿使用 unload 事件响应要关闭的窗口(或应用程序),而应使用 NativeApplication 对象的 exiting 事件检测关闭某一应用程序的时间。或者使用 NativeWindow 对象的 closing 事件检测关闭某一窗口的时间。例如,以下 JavaScript 代码将在用户关闭应用程序时显示 ("Goodbye.") 消息: var app = air.NativeApplication.nativeApplication; app.addEventListener(air.Event.EXITING, closeHandler); function closeHandler(event) { alert("Goodbye."); } 但是,脚本能够 成功响应因导航 frame、iframe 或顶级窗口内容而引起的 unload 事件。 注: Adobe AIR 的将来版本可能会删除这些限制。
JavaScript Window 对象Window 对象在 JavaScript 执行上下文中保持为全局对象。在应用程序沙箱中,AIR 向 JavaScript Window 对象添加了新属性,以便提供对 AIR 内置类和重要主机对象的访问。此外,某些方法和属性的行为会有所不同,这取决于它们是否位于应用程序沙箱中。
air.NativeApplication 对象NativeApplication 对象提供有关应用程序状态的信息,调度若干重要应用程序级别的事件,并提供用于控制应用程序行为的有用函数。将自动创建 NativeApplication 对象的单个实例,并且可通过用户定义的 NativeApplication.nativeApplication 属性访问该实例。 若要通过 JavaScript 代码访问该对象,您可以使用: var app = window.runtime.flash.desktop.NativeApplication.nativeApplication; 或者,如果已导入 AIRAliases.js 脚本,则可以使用以下简短形式: var app = air.NativeApplication.nativeApplication; NativeApplication 对象只能从应用程序沙箱内部访问。有关 NativeApplication 对象的详细信息,请参阅处理 AIR 运行时和操作系统信息。 JavaScript URL 方案在应用程序沙箱内部阻止执行在 JavaScript URL 方案(如在 href="javascript:alert('Test')" 中)定义的代码。不引发错误。 |
|