加载外部数据

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

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

使用 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。

在 AIR 中,您可以设置 URLRequest 类的其他属性,这些属性仅适用于在应用程序安全沙箱中运行的 AIR 内容。应用程序沙箱中的内容还可以使用新 URL 方案(除 file 和 http 等标准方案之外)定义 URL。

属性

说明

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 请求中使用的用户代理字符串。

注: HTMLLoader 类具有相关属性,用于设置与 HTMLLoader 对象加载的内容有关的设置。有关详细信息,请参阅 关于 HTMLLoader 类 。

设置 URLRequest 默认值(仅 AIR)

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

URLRequestDefaults.manageCookies = false; 
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 的请求的默认用户名和密码:

URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X"); 

URLRequestDefaults 设置仅适用于当前应用程序域,只有一个例外。传递到 setLoginCredentialsForHost() 方法的凭据用于 AIR 应用程序中任何应用程序域所发出的请求。

有关详细信息,请参阅 用于 Adobe Flash Platform 的 ActionScript 3.0 参考 中的 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:File = File.applicationDirectory; 
dir = dir.resolvePath("assets"); 
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:File = File.applicationStorageDirectory; 
prefsFile = prefsFile.resolvePath("prefs.xml"); 
trace(dir.prefsFile); // 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:URLVariables = new URLVariables( "one=1&two=2" ); 
urlVar.decode("amp=" + encodeURIComponent( "&" ) ); 
urlVar.three = 3; 
urlVar.amp2 = "&&"; 
trace(urlVar.toString()); //amp=%26&amp2=%26%26&one=1&two=2&three=3 
 
var urlRequest:URLRequest = new 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 类调度的事件包括 complete 、 httpStatus 、 ioError 、 open 、 progress 和 securityError 等。

ActionScript 3.0 事件处理模型与 ActionScript 2.0 模型有很大区别,后者使用 LoadVars.onData 、 LoadVars.onHTTPStatus 和 LoadVars.onLoad 事件处理程序。有关在 ActionScript 3.0 中处理事件的详细信息,请参阅 处理事件

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

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

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

var secondsUTC:Number = new Date().time; 
var dataXML:XML =  
    <clock> 
        <time>{secondsUTC}</time> 
    </clock>; 
var request:URLRequest = new URLRequest("http://www.yourdomain.com/time.cfm"); 
request.contentType = "text/xml"; 
request.data = dataXML.toXMLString(); 
request.method = URLRequestMethod.POST; 
var loader:URLLoader = new URLLoader(); 
loader.load(request); 

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

使用 URLStream 类

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

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

httpResponseStatus 事件 (AIR)

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

从外部文档加载数据

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

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

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

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

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

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

private function completeHandler(event:Event):void 
{ 
    var loader2:URLLoader = URLLoader(event.target); 
    var variables:URLVariables = new URLVariables(loader2.data); 
    trace(variables.dayNames); 
}

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

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

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

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

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

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

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

package 
{ 
    import flash.display.Sprite; 
    import flash.events.*; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
 
    public class URLLoaderDataFormatExample extends Sprite 
    { 
        public function URLLoaderDataFormatExample() 
        { 
            var request:URLRequest = new URLRequest("http://www.[yourdomain].com/params.txt"); 
            var variables:URLLoader = new URLLoader(); 
            variables.dataFormat = URLLoaderDataFormat.VARIABLES; 
            variables.addEventListener(Event.COMPLETE, completeHandler); 
            try 
            { 
                variables.load(request); 
            }  
            catch (error:Error) 
            { 
                trace("Unable to load URL: " + error); 
            } 
        } 
        private function completeHandler(event:Event):void 
        { 
        var loader:URLLoader = URLLoader(event.target); 
        trace(loader.data.dayNames); 
        } 
    } 
}
注: URLLoader.dataFormat 的默认值为 URLLoaderDataFormat.TEXT 。

如以下示例所示,从外部文件加载 XML 与加载 URLVariables 相同。可以创建 URLRequest 实例和 URLLoader 实例,然后使用它们下载远程 XML 文档。文件完全下载后,调度 Event.COMPLETE 事件,并将外部文件的内容转换为可使用 XML 方法和属性分析的 XML 实例。

package 
{ 
    import flash.display.Sprite; 
    import flash.errors.*; 
    import flash.events.*; 
    import flash.net.URLLoader; 
    import flash.net.URLRequest; 
 
    public class ExternalDocs extends Sprite 
    { 
        public function ExternalDocs() 
        { 
            var request:URLRequest = new URLRequest("http://www.[yourdomain].com/data.xml"); 
            var loader:URLLoader = new URLLoader(); 
            loader.addEventListener(Event.COMPLETE, completeHandler); 
            try 
            { 
                loader.load(request); 
            } 
            catch (error:ArgumentError) 
            { 
                trace("An ArgumentError has occurred."); 
            } 
            catch (error:SecurityError) 
            { 
                trace("A SecurityError has occurred."); 
            } 
        } 
        private function completeHandler(event:Event):void 
        { 
            var dataXML:XML = XML(event.target.data); 
            trace(dataXML.toXMLString()); 
        } 
    } 
}

与外部脚本进行通信

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

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

var variables:URLVariables = new URLVariables("name=Franklin"); 
var request:URLRequest = new URLRequest(); 
request.url = "http://www.[yourdomain].com/greeting.cfm"; 
request.method = URLRequestMethod.POST; 
request.data = variables; 
var loader:URLLoader = new URLLoader(); 
loader.dataFormat = URLLoaderDataFormat.VARIABLES; 
loader.addEventListener(Event.COMPLETE, completeHandler); 
try 
{ 
    loader.load(request); 
} 
catch (error:Error) 
{ 
    trace("Unable to load URL"); 
} 
 
function completeHandler(event:Event):void 
{ 
    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>