加载外部数据

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

AIR 运行时包括从外部源加载数据的机制。这些源可以提供静态内容(例如文本文件)或动态内容(例如 Web 脚本生成的内容)。可以使用多种方法来设置数据的格式,并且运行时提供了用于解码和访问数据的相关功能。也可以在检索数据的过程中将数据发送到外部服务器。

使用 URLRequest 类

加载外部数据的许多 API 使用 URLRequest 类来定义所需网络请求的属性。

URLRequest 属性

您可以在任何安全沙箱中设置 URLRequest 对象的下列属性:

属性

说明

contentType

使用 URL 请求发送的任何数据的 MIME 内容类型。如果未设置 contentType,则值将作为 application/x-www-form-urlencoded 发送。

data

一个对象,它包含将随 URL 请求一起传输的数据。

digest

唯一标识要存储为(或从其检索)Adobe® Flash® Player 缓存的已签名 Adobe 平台组件的字符串。

method

HTTP 请求方法,例如 GET 或 POST。(AIR 应用程序安全域中运行的内容可将除"GET""POST"之外的字符串指定为 method 属性。允许任何 HTTP 动词,"GET"为默认方法。请参阅AIR 安全性。)

requestHeaders

要追加到 HTTP 请求的 HTTP 请求标头的数组。请注意,在 Flash Player 以及在应用程序安全沙箱外运行的 AIR 内容中,设置一些标题的权限时会受到限制。

url

指定要请求的 URL。

URLRequest 类包括以下只可用于 AIR 应用程序安全沙箱中的内容的属性:

属性

说明

followRedirects

指定是否要遵循重定向(默认值为 true;如果不遵循,则为 false)。仅 AIR 应用程序沙箱支持此属性。

manageCookies

指定 HTTP 协议堆栈是否应管理此请求的 cookie(默认值为 true;如果不管理,则为 false)。仅 AIR 应用程序沙箱支持设置此属性。

authenticate

指定是否应为此请求处理身份验证请求(如果是,则为 true)。仅 AIR 应用程序沙箱支持设置此属性。默认为对请求进行身份验证 — 如果服务器要求提供凭据,则可能会显示身份验证对话框。您还可以使用 URLRequestDefaults 类设置用户名和密码 — 请参阅设置 URLRequest 默认值(仅 AIR)

cacheResponse

指定是否为此请求缓存响应数据。仅 AIR 应用程序沙箱支持设置此属性。默认值为缓存响应 (true)。

useCache

指定在此 URLRequest 获取数据之前是否应查询本地缓存。仅 AIR 应用程序沙箱支持设置此属性。默认值 (true) 为使用本地缓存版本(如果可用)。

userAgent

指定要在 HTTP 请求中使用的用户代理字符串。

设置 URLRequest 默认值(仅 AIR)

借助 URLRequestDefaults 类,您可以定义 URLRequest 对象的应用程序特定默认设置例如,以下代码设置 manageCookiesuseCache 属性的默认值。所有新 URLRequest 对象将使用这些属性的指定值,而不是常规默认值:

air.URLRequestDefaults.manageCookies = false; 
air.URLRequestDefaults.useCache = false;
注: URLRequestDefaults 类仅针对 Adobe AIR 中运行的内容进行定义。Flash Player 中不支持该类。

URLRequestDefaults 类包含 setLoginCredentialsForHost() 方法,使用该方法可指定要为特定主机使用的默认用户名和密码。该方法的 hostname 参数中定义的主机可以为域(例如"www.example.com")或域加端口号(例如"www.example.com:80")。请注意,"example.com""www.example.com""sales.example.com"均视为唯一的主机。

只有在服务器要求提供凭据时才会使用这些凭据。如果用户已通过身份验证(例如,使用身份验证对话框),则调用 setLoginCredentialsForHost() 方法不会更改通过身份验证的用户。

以下代码设置用于发送到 www.example.com 的请求的默认用户名和密码:

air.URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X");
URLRequestDefaults 设置仅适用于当前应用程序域,只有一个例外。传递到 setLoginCredentialsForHost() 方法的凭据用于 AIR 应用程序中任何应用程序域所发出的请求。

有关详细信息,请参阅针对 HTML 开发人员的 Adobe AIR API 参考中的 URLRequestDefaults 类。

URI 方案

标准 URI 方案(例如下列方案)可以用于任何安全沙箱所发出的请求:

http: 和 https:

将这些用于标准 Internet URL(与在 Web 浏览器的使用方式相同)。

文件:

使用 file: 指定位于本地文件系统中的文件的 URL。例如:

file:///c:/AIR Test/test.txt 

在 AIR 中,您还可以在定义在应用程序安全性沙箱中运行的内容的 URL 时使用下列方案:

app:

使用 app: 指定相对于安装的应用程序的根目录的路径。例如,以下路径指向应用程序安装目录的 resources 子目录:

app:/resources 

使用 AIR Debug Launcher (ADL) 启动 AIR 应用程序时,应用程序目录是包含应用程序描述符文件的目录。

使用 File.applicationDirectory 创建的 File 对象的 URL(和 url 属性)使用 app URI 方案,如下所示:

var dir = air.File.applicationDirectory; 
dir = dir.resolvePath("assets"); 
air.trace(dir.url); // app:/assets

app-storage:

使用 app-storage: 指定相对于应用程序的数据存储目录的路径。AIR 为安装的每个应用程序(和用户)都创建了唯一的应用程序存储目录,这些目录对于存储特定于各个应用程序的数据非常有用。例如,以下路径指向应用程序存储目录的 settings 子目录中的 prefs.xml 文件:

app-storage:/settings/prefs.xml 

使用 File.applicationStorageDirectory 创建的 File 对象的 URL(和 url 属性)使用 app-storage URI 方案,如下所示:

var prefsFile = air.File.applicationStorageDirectory; 
prefsFile = prefsFile.resolvePath("prefs.xml"); 
air.trace(prefsFile.url); // app-storage:/prefs.xml

mailto:

在传递给 navigateToURL() 函数的 URLRequest 对象中可以使用 mailto 方案。请参阅在其他应用程序中打开 URL

您可以使用 URLRequest 对象(使用这些 URI 方案中的任何一个方案)定义许多不同对象(例如 FileStream 或 Sound 对象)的 URL 请求。还可以在 AIR 中运行的 HTML 内容中使用这些方案;例如,可以在 img 标签的 src 属性中使用它们。

但是,您仅可以使用应用程序安全沙箱中的内容中的 AIR 特定 URI 方案(app:app-storage:)。有关详细信息,请参阅 AIR 安全性

设置 URL 变量

当可以直接向 URL 字符串添加变量时,可以更轻松地使用 URLVariables 类来定义请求所需要的任何变量。

可以使用三个方法向 URLVariables 对象添加参数:

  • 在 URLVariables 构造函数中

  • 使用 URLVariables.decode() 方法

  • 作为 URLVariables 对象自身的动态属性

以下示例演示了全部三个方法以及如何将变量分配到 URLRequest 对象:

var urlVar = new air.URLVariables( "one=1&two=2" ); 
urlVar.decode("amp=" + air.encodeURIComponent( "&" ) ); 
urlVar.three = 3; 
urlVar.amp2 = "&&"; 
air.trace(urlVar.toString()); //amp=%26&amp2=%26%26&one=1&two=2&three=3 
 
var urlRequest = new air.URLRequest( "http://www.example.com/test.cfm" ); 
urlRequest.data = urlVar;

当在 URLVariables 构造函数或在 URLVariables.decode() 方法中定义变量时,请确保 URL 编码在 URI 字符串中包含特定含义的字符。例如,当在参数名称或值中使用 & 符时,必须通过将其从 & 更改为 %26 来编码该 & 符,因为 & 符用作分隔符。顶级 encodeURIComponent() 函数可以用于此目的。

使用 URLLoader 类

借助 URLLoader 类,您可以向服务器发送请求并访问返回的信息。您也可以使用 URLLoader 类来访问允许访问本地文件的上下文中(例如 Flash Player 只能与本地文件系统内容交互的沙箱和 AIR 应用程序沙箱)的本地文件系统上的文件。URLLoader 类以文本、二进制数据或 URL 编码变量形式从 URL 下载数据。URLLoader 类调度的事件包括 completehttpStatusioErroropenprogresssecurityError 等。

URLLoader 类为 XMLHttpRequest 类提供了替代项。您可以使用两种类中任意一种通过 HTTP 请求下载数据。

下载完成之前,下载的数据不可用。可通过侦听要调度的 progress 事件监视下载进度(已加载字节数和总字节数)。但是,如果文件加载足够快,可能不调度 progress 事件。成功下载文件后,将调度 complete 事件。通过设置 URLLoader dataFormat 属性,您可以以文本、原始二进制数据或 URLVariables 对象格式接收数据。

URLLoader.load() 方法(并且可能 URLLoader 类的构造函数)使用单个参数,request,该参数是 URLRequest 对象。URLRequest 对象包含所有用于单一 HTTP请求的信息,例如目标 URL、请求方法(GETPOST)、其他标题信息和 MIME 类型。

例如,若要将 XML 数据包上载到服务器端脚本,可以使用以下代码:

var secondsUTC = new Date().time; 
var dataXML = (new DOMParser()).parseFromString( "<time>" + secondsUTC + "</time>", "application/xml" ); 
var request = new air.URLRequest("http://www.example.com/time.cfm"); 
request.contentType = "text/xml"; 
request.data = dataXML; 
request.method = air.URLRequestMethod.POST; 
var loader = new air.URLLoader(); 
loader.load(request);

上一个代码片断创建包含要发送到服务器的 XML 包的名为 dataXML 的 XML 文档。此示例将 URLRequest contentType 属性设置为 "text/xml" 并将 XML 文档分配给 URLRequest data 属性。最后,示例创建 URLLoader 对象并通过使用 load() 方法将请求发送到远程脚本。

使用 URLStream 类

数据到达时,URLStream 类将提供对下载的数据的访问。并且 URLStream 类还允许在完成下载前关闭流。下载的数据以原始二进制数据的形式提供。

当从 URLStream 对象读取数据时,使用 bytesAvailable 属性确定在读取数据之前是否提供了足够的数据。当您尝试阅读的数据比可用数据多时,将引发 EOFError 异常。

httpResponseStatus 事件 (AIR)

URLStream 类在传送任何响应数据之前将调度 httpResponseStatus 事件。httpResponseStatus 事件(由 HTTPStatusEvent 类表示)包括 responseURL 属性(该属性是返回响应的 URL)和 responseHeaders 属性(该属性是表示响应返回的响应标题的 URLRequestHeader 对象的数组)。

从外部文档加载数据

构建动态应用程序时,从外部文件或从服务器端脚本加载数据会很有用。这样,您不必编辑或重新编译应用程序,即可生成动态应用程序。例如,如果您要构建一个“每日提示”应用程序,就可以编写一个服务器端脚本,该脚本每天从数据库检索一次随机提示并将其保存到文本文件。然后,应用程序可以加载静态文本文件的内容,而不必每次查询数据库。

下面的片断创建 URLRequest 和 URLLoader 对象,用于加载外部文本文件 params.txt 的内容:

var request = new air.URLRequest("params.txt"); 
var loader = new air.URLLoader(); 
loader.load(request);
默认情况下,如果您未定义请求方法,则 Flash Player 和 Adobe AIR 会使用 HTTP GET 方法加载内容。要使用 POST 方法发送请求,可使用静态常量 URLRequestMethod.POSTrequest.method 属性设置为 POST,如以下代码所示:
var request = new air.URLRequest("http://www.example.com/sendfeedback.cfm"); 
request.method = air.URLRequestMethod.POST;

在运行时加载的外部文档 params.txt 包含以下数据:

monthNames=January,February,March,April,May,June,July,August,September,October,November,December&dayNames=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday

该文件包含两个参数,即 monthNamesdayNames。每个参数包含一个逗号分隔列表,该列表被分析为字符串。可以使用 String.split() 方法将此列表拆分为数组。

不要将保留字或语言构造作为外部数据文件中的变量名称,因为这样做会使代码的读取和调试变得更困难。
加载数据后,将调度 complete 事件,随后就可以在 URLLoader 的 data 属性中使用外部文档的内容,如以下代码所示:
function completeHandler(event) 
{ 
    var loader2 = URLLoader(event.target); 
    air.trace(loader2.data); 
}

如果远程文档包含名称-值对,则可以通过传入加载文件的内容,使用 URLVariables 类来分析数据,如下所示:

function completeHandler(event) 
{ 
    var loader2 = event.target; 
    var variables = new air.URLVariables(loader2.data); 
    air.trace(variables.dayNames); 
}

外部文件中的各个名称-值对都创建为 URLVariables 对象中的一个属性。在上面的代码范例中,变量对象中的各个属性都被视为字符串。如果名称-值对的值是一个项目列表,则可以通过调用 String.split() 方法将字符串转换为数组,如下所示:

var dayNameArray = variables.dayNames.split(",");
如果从外部文本文件加载数值数据,可使用顶级函数(如 parseInt()parseFloat()Number())将这些值转换为数值。

无需将远程文件的内容作为字符串加载和新建 URLVariables 对象,您可以将 URLLoader.dataFormat 属性设置为在 URLLoaderDataFormat 类中找到的静态属性之一。URLLoader.dataFormat 属性有以下三个可能的值:

  • URLLoaderDataFormat.BINARYURLLoader.data 属性包含 ByteArray 对象中存储的二进制数据。

  • URLLoaderDataFormat.TEXTURLLoader.data 属性包含 String 对象中的文本。

  • URLLoaderDataFormat.VARIABLESURLLoader.data 属性包含 URLVariables 对象中存储的 URL 编码的变量。

下面的代码演示了如何通过将 URLLoader.dataFormat 属性设置为 URLLoaderDataFormat.VARIABLES,从而自动将加载的数据分析为 URLVariables 对象:

var request = new air.URLRequest("http://www.example.com/params.txt"); 
var variables = new air.URLLoader(); 
variables.dataFormat = air.URLLoaderDataFormat.VARIABLES; 
variables.addEventListener(air.Event.COMPLETE, completeHandler); 
try 
{ 
    variables.load(request); 
}  
catch (error) 
{ 
    air.trace("Unable to load URL: " + error); 
} 
 
function completeHandler(event) 
{ 
    var loader = event.target; 
    air.trace(loader.data.dayNames); 
}
注: URLLoader.dataFormat 的默认值为 URLLoaderDataFormat.TEXT

如以下示例所示,从外部文件加载 XML 与加载 URLVariables 相同。可以创建 URLRequest 实例和 URLLoader 实例,然后使用它们下载远程 XML 文档。文件完全下载后,将调度 complete 事件,trace() 函数将该文件的内容输出到命令行。

 
var request = new air.URLRequest("http://www.example.com/data.xml"); 
var loader = new air.URLLoader(); 
loader.addEventListener(air.Event.COMPLETE, completeHandler); 
loader.load(request); 
 
function completeHandler(event) 
{ 
    var dataXML = event.target.data; 
    air.trace(dataXML); 
}

与外部脚本进行通信

除了加载外部数据文件,还可以使用 URLVariables 类将变量发送到服务器端脚本并处理服务器的响应。这是非常有用的,例如,如果您正在编写游戏,想要将用户的得分发送到服务器以计算是否应添加到高分列表中,甚至想要将用户的登录信息发送到服务器以进行验证。服务器端脚本可以处理用户名和密码,向数据库验证用户名和密码,然后返回用户提供的凭据是否有效的确认。

下面的片断创建一个名为 variables 的 URLVariables 对象,该对象创建称为 name 的新变量。接下来,创建一个 URLRequest 对象,该对象指定变量要发送到的服务器端脚本的 URL。然后,设置 URLRequest 对象的 method 属性,以便将变量作为 HTTP POST 请求发送。为了将 URLVariables 对象添加到 URL 请求,需要将 URLRequest 对象的 data 属性设置为早先创建的 URLVariables 对象。最后,创建 URLLoader 实例并调用 URLLoader.load() 方法,此方法用于启动该请求。

var variables = new air.URLVariables("name=Franklin"); 
var request = new air.URLRequest(); 
request.url = "http://www.[yourdomain].com/greeting.cfm"; 
request.method = air.URLRequestMethod.POST; 
request.data = variables; 
var loader = new air.URLLoader(); 
loader.dataFormat = URLLoaderDataFormat.VARIABLES; 
loader.addEventListener(Event.COMPLETE, completeHandler); 
try 
{ 
    loader.load(request); 
} 
catch (error) 
{ 
    air.trace("Unable to load URL"); 
} 
 
function completeHandler(event) 
{ 
    air.trace(event.target.data.welcomeMessage); 
}

下面的代码包含上面的示例中使用的 Adobe ColdFusion® greeting.cfm 文档的内容:

<cfif NOT IsDefined("Form.name") OR Len(Trim(Form.Name)) EQ 0> 
    <cfset Form.Name = "Stranger" /> 
</cfif> 
<cfoutput>welcomeMessage=#UrlEncodedFormat("Welcome, " & Form.name)# 
</cfoutput>