AS代码2.0:针对Flash Player 7
Flash Player 7比以前的Flash播放器支持更多的动作脚本命令,可以使用这些命令来编写更稳健的脚本。不过,如果在现有的脚本中使用了这些命令,并针对Flash 7播放器发布该脚本,它也许不能正确工作。例如,如果你有一个脚本,其中有一个函数名使用了Error,该脚本也许可以正确编译,但并不能按照Flash 7播放器的方式运行,因为在现在的动作脚本语言中Error是一个内建类(因此,Error是一个保留字)。可以通过修改脚本,把Error函数名改为其它名字来解决,如ErrorCondition。
Flash 7播放器也有了很多变化,这些变化影响到一个SWF文件怎样访问另一个SWF文件,怎样载入外部数据,怎样访问本地设置和数据(如隐私设置和本地永久共享对象)。最后,一些现有的特性也已经改变。
如果你现有的脚本是针对Flash 6或更早版本的播放器编写的,但又想针对Flash 7播放器发布,你可能需要修改你的脚本,以便它们符合Flash 7播放器的执行要求并能按设计思路工作。下面我们就介绍这些相关知识。
一、遵从ECMA-262 Edition 4方案
Flash 7播放器作了一些修改,使之更加符合 ECMA-262 Edition 4方案。在动作脚本语言2.0中,除了可以使用基于类的编程技术外,也增加了其它特性,某些行为也已修改。当你针对Flash 7播放器发布且使用动作脚本语言2.0时,你可以不把一种对象类型指派给另一个。这些功能不要求你更新现有的脚本,但是,如果你针对 Flash 7播放器发布发布你的脚本,你可以使用这些功能,然后继续修订和改进。
与上面提到的变化不同,下表列出的变化(其中也有一些不完全遵从ECMA 方案)可能导致现有脚本的执行结果与以前不同。如果你在针对 Flash 7播放器发布的现有脚本中使用了这些特性,请查看一下这些变化,确保你的代码能够按照设计计划运行,或确定是否需要重写代码。特别是,计算 undefined(未定义)项的结果在某些情况下是不同的,你应该在针对Flash 7播放器发布的脚本中初始化所有的变量。
针对Flash 7播放器发布的SWF文件 | 针对早期Flash播放器发布的SWF文件 |
支持区分大小写(只是大小写不同的变量名被解释为不同的变量)。这种变化也影响用#include指令载入的文件和使用 LoadVars.load()命令载入的外部变量。 | 不区分大小写(只是大小写不同的变量名被解释为相同的变量)。 |
在数值上下文中计算undefined项的返回结果是NaN。 | 在数值上下文中计算undefined项的返回结果是0。 |
myCount +=1; trace(myCount); // NaN |
myCount +=1; trace(myCount); // 1 |
当undefined项被转换为字符串时,其结果是undefined。 | 当undefined项被转换为字符串时,其结果是""(空字符串)。 |
firstname = "Joan "; lastname = "Flender"; trace(firstname + middlename + lastname); // Joan undefinedFlender |
firstname = "Joan "; lastname = "Flender"; trace(firstname + middlename + lastname); // Joan Flender |
当把字符串转换为逻辑值时,如果该字符串的长度>0,其结果为true;如果该字符串为空串,其结果为false。 | 当把字符串转换为逻辑值时,首先把它转换为数值,如果该数值非0,其结果为true,否则为false。 |
当设置数组的长度时,只有有效的数字字符串可设置长度。例如,"6"起作用,但" 6"或"6xyz"不起作用。 | 当设置数组的长度时,即使是一个畸形的数字字符串也可设置长度: |
my_array=new Array(); my_array[" 6"] ="x"; trace(my_array.length); // 0 my_array["6xyz"] ="x"; trace(my_array.length); // 0 my_array["6"] ="x"; trace(my_array.length); // 7 |
my_array=new Array(); my_array[" 6"] ="x"; trace(my_array.length); // 7 my_array["6xyz"] ="x"; trace(my_array.length); // 7 my_array["6"] ="x"; trace(my_array.length); // 7 |
二、设置和本地数据的域名规则
在Flash 6播放器中,当访问本地设置(如摄像机或麦克风访问许可)或本地永久数据(共享对象)时,默认使用超域匹配规则。也就是说,存放在 here.xyz.com、 there.xyz.com和 xyz.com的SWF文件的设置和数据是共享的,且都存储在xyz.com中。
在Flash 7播放器中,默认使用精确域匹配规则。也就是说,存放在 here.xyz.com的文件的设置和数据存储在 here.xyz.com中,存放在 there.xyz.com的文件的设置和数据存储在 there.xyz.com中,等等。
新的属性System.exactSettings让你指定使用哪种规则。这个属性支持针对在Flash 6或更高版本播放器发布的文件。对于针对Flash 6播放器发布的文件,本属性的默认值是false,这意味着使用超域匹配规则。对于针对Flash 7播放器发布的文件,本属性的默认值是true,这意味着使用精确域匹配规则。
如果你使用设置和永久本地数据,且想要针对Flash 7播放器发布一个Flash 6播放器的SWF文件,你可能需要在发布的文件中把本属性值设置为 false。
三、SWF文件之间的跨域和子域访问
当你开发一系列互相通讯的SWF文件时,例如,当使用 loadMovie()、 MovieClip.loadMovie()、 MovieClipLoader.LoadClip() 命令或本地连接对象时,你可能把这些动画文件存放在不同的域或一个超域的不同的子域中。
在针对Flash 5或更早版本的播放器发布的文件中,跨域或子域访问不受限制。
在针对Flash 6播放器发布的文件中,你可以使用 LocalConnection.allowDomain事件处理函数或 System.security.allowDomain()方法来指定允许跨域访问(例如,让在 someOtherSite.com域的文件访问在 someSite.com域的文件),且无需用命令来允许子域访问(例如,在 store.someSite.com子域的文件可以访问在 www.someSite.com子域的文件)。
在针对Flash 7播放器发布的文件中,SWF文件之间的访问与早期版本有两个方面的不同。首先,Flash 7播放器执行精确域匹配而不是超域匹配规则。因此,被访问的文件(即使是针对早期的Flash播放器版本而不是Flash 7播放器发布的文件)必须显式指定允许跨域或子域访问。其次,存放在使用安全协议(HTTPS)站点中的文件,必须显式指定允许来自使用不安全协议(HTTP或FTP)的站点的文件的访问。
因为Flash 7播放器执行精确域匹配而不是超域匹配规则,如果你想要针对Flash 7播放器发布的文件能够访问你现有的脚本,你可能需要修改这些脚本。(你仍然可以针对Flash 6播放器发布修改过的文件。)
如果你在文件中使用 LocalConnection.allowDomain()或 System.security.allowDomain()语句,并指定允许访问超域站点,你必须修改你的参数来指定准确的域。下面的代码说明你可能需要进行的修改:
// 允许存放在 www.someSite.co
m或 store.someSite.com域的SWF文件访问 System.security.allowDomain("someSite.com"); // 存放在www.anyOldSite.com域的SWF文件中的 Flash 6播放器命令 my_lc.allowDomain = function(sendingDomain){ return(sendingDomain=="someSite.com"); } // 允许针对Flash 7播放器发布的SWF文件访问的对应命令 System.security.allowDomain("www.someSite.com", "store.someSite.com"); my_lc.allowDomain = function(sendingDomain) { return(sendingDomain=="www.someSite.com" || sendingDomain=="store.someSite.com"); }
如果你当前还没有使用这些语句,你也可能需要添加这样的语句。
例如,如果你的SWF文件存放在 www.someSite.com域,且你想允许存放在 store.someSite.com域针对 Flash 7播放器发布的SWF文件访问,你必须给存放在 www.someSite.com域的文件添加下列语句(你仍然可以针对Flash 6播放器发布存放在 www.someSite.com的文件):
System.security.allowDomain ("store.someSite.com"); my_lc.allowDomain = function(sendingDomain) { return(sendingDomain==" store.someSite.com"); }
总的来说,如果你针对Flash 7播放器发布文件且符合以下条件,你可能要修改你的文件,添加或修改allowDomain语句:
①你编写跨SWF文件的脚本
使用loadMovie()、MovieClip.loadMovie()、 MovieClipLoader.LoadClip()或本地连接对象。
②被调用的SWF文件(任何版本)不是存放在使用安全协议(HTTPS)的站点,或调用的和被调用的SWF文件都存放在使用安全协议(HTTPS)的站点。
③SWF文件不在相同的域
例如,一个文件在www.domain.com,另一个在 store.domain.com。
为此你需要做以下修改:
①如果被调用的SWF文件是针对Flash 7播放器发布的,在被调用的SWF文件中包含 System.security.allowDomain或 LocalConnection.allowDomain语句,使用精确域名匹配。
②如果被调用的SWF文件是针对Flash 6播放器发布的,修改被调用的SWF文件,添加或修改 System.security.allowDomain或 LocalConnection.allowDomain语句,使用精确域名匹配(如本节前面的代码所示)。你可以针对Flash 6或7播放器发布修改过的文件。
③如果被调用的SWF文件是针对Flash 5 或以前的播放器版本发布的,针对Flash 6或7播放器发布被调用的SWF文件,添加 System.security. allowDomain语句,使用精确域名匹配(如本节前面的代码所示)。(Flash 5及以前的播放器版本不支持本地连接对象。)
四、SWF文件之间从HTTP到HTTPS协议的访问
正如前一节所讨论的,在Flash 7播放器中,跨域和子域访问的规则已经修改。除了现在执行精确域匹配规则外,你必须显式说明允许存放在使用不安全协议的站点的文件访问存放在使用安全协议(HTTPS)的站点的文件。根据被调用的文件是针对Flash 7播放器还是针对Flash 6播放器发布的,你必须执行一个 allowDomain语句,或使用新的 LocalConnection.allowInsecureDomain事件处理函数或System.security.allowInsecureDomain()语句。
警告:执行allowInsecureDomain()语句危及HTTPS协议提供的安全。只有在你不能重新组织你的站点以便所有的SWF文件都能接受 HTTPS协议的服务时才做这样的修改。
下面的代码说明你可能需要做的修改:
// 允许存放在http://www.someSite.com或 http://www.someOtherSite.com // 针对Flash 7播放器发布的SWF文件访问的存放在 https://www.someSite.com // 针对Flash 6播放器发布的SWF文件中的命令 my_lc.allowDomain = function(sendingDomain) { return(sendingDomain=="someOtherSite.com"); } // 允许针对Flash 7播放器发布的 // 存放在http://www.someSite.com或 http://www.someOtherSite.com的 // 针对Flash 7播放器发布的SWF文件访问的对应命令 System.security.allowInsecureDomain(" www.someSite.com", "www.someOtherSite.com"); my_lc.allowInsecureDomain = function(sendingDomain) { return(sendingDomain=="www.someSite.com" || sendingDomain=="www.someOtherSite.com"); }
如果你当前还没有使用这些语句,你也可能需要添加这样的语句。
即使两个文件都在相同的域也可能需要修改(例如,存放 http://www.domain.com的文件调用存放在 https://www.domain.com的文件)。
总的来说,如果你针对Flash 7播放器发布文件且符合以下条件,你可能要修改你的文件,添加或修改语句:
①你编写跨SWF文件的脚本(使用loadMovie()、 MovieClip.loadMovie()、 MovieClipLoader.LoadClip()或本地连接对象)。
②调用文件没有存放在使用 HTTPS协议的站点和被调用的SWF文件存放在使用安全协议(HTTPS)的站点。
你必须做以下修改:
①如果被调用的SWF文件是针对Flash 7播放器发布的,在被调用的SWF文件中包含 System.security.allowDomain或 LocalConnection.allowDomain语句,使用精确域名匹配(如本节前面的代码实例所示)。即使调用的和被调用的 SWF文件存放在相同的域,也需要这个语句。
②如果被调用的SWF文件是针对Flash 6或以前的播放器版本发布的,且调用的和被调用的文件都存放在相同的域(例如,存放http://www.domain.com的文件调用存放在 https://www.domain.com的文件),不需要修改。
③如果被调用的SWF文件是针对Flash 6播放器版本发布的,调用的和被调用的文件不在相同的域,而你又不想针对Flash 7播放器导出被调用文件,就要修改被调用文件,添加或修改 System.security.allowDomain或 LocalConnection.allowDomain 语句,使用精确域名匹配(如本节前面的代码实例所示)。
④如果被调用的SWF文件是针对Flash 6播放器版本发布的,而你又想针对Flash 7播放器发布被调用文件,就在被调用文件中包含 System. security.allowDomain或 LocalConnection.allowDomain语句,使用精确域名匹配(如本节前面的代码实例所示)。即使两个文件都存放在相同的域,也需要这个语句。
⑤如果被调用的SWF文件是针对Flash 5或以前的播放器版本发布的,且两个文件不在相同的域,你可以做两件事情。你可以针对 Flash 6播放器发布被调用文件或修改 System.security.allowDomain 语句,使用精确域名匹配(如本节前面的代码所示);或者你可以针对Flash 7播放器发布被调用文件,使用精确域名匹配(如本节前面的代码实例所示)。
五、允许访问数据的服务器端策略文件
使用这些数据装载调用,Flash文档可以从外部源载入数据: XML.load()、XML.sendAndLoad()、 LoadVars.load()、LoadVars. sendAndLoad()、loadVariables()、 loadVariablesNum()、 MovieClip.loadVariables()、 XMLSocket.connect()和 Macromedia Flash Remoting (NetServices.createGatewayConnection)。SWF文件也可以在运行期导入运行期共享库(RSL)或其它SWf文件中定义的资源。在默认情况下,被导入的数据或 RSL必须存储在与装载这些外部数据或媒体的SWF文件相同的域。
要使来自不同域的SWF文件能够使用数据和运行期共享库中的资源,你应该使用跨域策略文件。跨域策略文件是一个XML文件,它为服务器提供一种方法来指明它的数据和文档对来自某些域或所有域的 SWF文件是可用的。任何一个来自服务器策略文件中指定的域的SWF文件都允许访问该服务器的数据或RSL。
如果你在装载外部数据,即使你不打算针对 Flash 7播放器发布任何文件,你也应该创建策略文件。如果你正在使用 RSL,且针对 Flash 7播放器发布调用的和被调用的文件,你应该创建策略文件。