AS3(ActionScript 3)与JavaScript(JS)的通讯主要应用于Flash/Flex应用与网页交互的场景,例如在嵌入SWF文件的HTML页面中,需要让Flash调用JS函数操作DOM(如弹窗、获取页面数据),或让JS调用Flash内部方法(如控制播放器、获取用户操作数据),尽管随着HTML5的普及,Flash使用场景大幅减少,但在一些遗留系统或特定多媒体交互需求中,两者通讯仍具实用价值,本文将详细介绍AS3与JS通讯的核心方法、实现逻辑及注意事项。

核心通讯方法:ExternalInterface
ExternalInterface是Adobe官方提供的AS3与JS通讯的标准化接口,支持双向调用(AS3调用JS、JS调用AS3),是两者通讯的首选方案,其原理基于浏览器提供的“桥接”机制,允许SWF与宿主页面(HTML)直接交换数据。
AS3调用JS函数
AS3通过ExternalInterface.call()方法调用JS函数,语法为:ExternalInterface.call("jsFunctionName", [param1, param2, ...])jsFunctionName为JS中定义的函数名,param为传递给JS函数的参数(支持基本数据类型、数组、对象等复杂类型,但需注意序列化问题)。
示例:
AS3端:
if (ExternalInterface.available) { // 调用JS的alert函数,传递字符串参数 ExternalInterface.call("alert", "Hello from AS3!"); // 调用JS的获取页面标题函数 var pageTitle:String = ExternalInterface.call("document.title") as String; trace("页面标题:" + pageTitle); } else { trace("ExternalInterface不可用"); }JS端(需在HTML中定义):
function showAlert(message) { alert(message); } // AS3调用document.title时,直接返回页面标题注意事项:
调用前需检查
ExternalInterface.available属性,避免在浏览器不支持(如某些移动端浏览器)或SWF未加载完成时调用。参数传递时,AS3的Object类型会被转换为JS的Object,但AS3的Date、Array等需确保JS端能正确解析(建议使用JSON序列化)。
JS调用AS3函数
JS调用AS3函数需分两步:
第一步(AS3端):通过ExternalInterface.addCallback()注册一个可被JS调用的函数,语法为:ExternalInterface.addCallback("asFunctionName", asFunctionHandler)asFunctionName为JS端调用的函数名,asFunctionHandler为AS3中定义的处理函数。
第二步(JS端):通过SWF对象获取AS3注册的函数并调用,JS端可通过document.getElementById("swfId")或swfobject.getObjectById("swfId")获取SWF元素,然后调用其注册的函数。

示例:
AS3端:
if (ExternalInterface.available) { // 注册名为"getFlashData"的函数,供JS调用 ExternalInterface.addCallback("getFlashData", function():String { return "这是Flash中的数据"; }); // 注册名为"setFlashVolume"的函数,接收JS传递的音量参数 ExternalInterface.addCallback("setFlashVolume", function(volume:Number):void { trace("设置音量为:" + volume); }); }JS端:
// 获取SWF元素(假设SWF的id为"mySwf") var flashObj = document.getElementById("mySwf"); // 调用AS3的getFlashData函数 var flashData = flashObj.getFlashData(); console.log(flashData); // 输出:"这是Flash中的数据" // 调用AS3的setFlashVolume函数,传递参数50 flashObj.setFlashVolume(50);注意事项:
AS3注册函数需在SWF完全加载后(监听
Event.INIT事件)执行,否则JS可能无法调用。JS端调用时需确保SWF已加载完成(可通过
swfobject.onload或window.onload判断)。
其他通讯方法
除ExternalInterface外,还有几种间接通讯方式,适用于特定场景:
LocalConnection
LocalConnection允许同一台机器上的不同SWF之间通讯,也可用于SWF与JS通讯(通过JS作为“中转”),原理是基于本地进程间的消息传递,无需HTTP请求,适合高频、低延迟的本地数据交互。
局限性:仅限同一浏览器标签页或同源页面,且无法跨域。
URLVariables + HTTP请求
AS3可通过URLLoader发送HTTP请求(GET/POST)到JS处理的服务器接口,JS端接收请求后返回数据(如JSON格式),适合异步通讯,但无法实现实时双向调用。
示例:AS3发送请求到/api/data,JS后端处理并返回响应数据。
SharedObject
SharedObject是AS3的本地存储机制,类似于Cookie,可用于在SWF和JS之间共享简单数据(如用户设置),但数据同步需依赖页面刷新或手动触发,非实时通讯。

通讯注意事项
安全性:
- ExternalInterface受浏览器同源策略限制,仅允许同域JS调用AS3函数;若需跨域,需在AS3中设置
Security.allowDomain("目标域名")。 - 避免直接执行JS代码(如
ExternalInterface.call("eval", "jsCode")),防止XSS攻击。
- ExternalInterface受浏览器同源策略限制,仅允许同域JS调用AS3函数;若需跨域,需在AS3中设置
兼容性:
- ExternalInterface在IE10以下需ActiveX支持,部分浏览器(如移动端Safari)可能禁用,需做好降级处理(如使用
navigateToURL替代)。
- ExternalInterface在IE10以下需ActiveX支持,部分浏览器(如移动端Safari)可能禁用,需做好降级处理(如使用
异步处理:
JS调用AS3函数时,若AS3函数耗时较长(如网络请求),需通过回调或事件机制返回结果,避免阻塞JS线程。
错误处理:
- 捕获
SecurityErrorError(跨域)、ReferenceError(函数未定义)等异常,确保通讯失败时程序不崩溃。
- 捕获
通讯方式对比
| 方法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| ExternalInterface | 浏览器桥接接口 | 双向直接调用,支持复杂类型 | 同源策略限制,部分浏览器兼容性差 | 实时双向交互(如控制播放器、弹窗) |
| LocalConnection | 本地进程消息传递 | 高效,低延迟 | 仅限本地同源页面 | 同机器多SWF或SWF与JS本地交互 |
| URLVariables+HTTP | HTTP请求/响应 | 跨域支持,异步灵活 | 非实时,需服务器支持 | 数据提交、异步数据获取 |
| SharedObject | 本地存储 | 数据持久化 | 非实时,需手动同步 | 用户设置、简单数据共享 |
相关问答FAQs
Q1:AS3与JS通讯时遇到跨域问题,如何解决?
A:若JS与SWF不同域,需在AS3中添加跨域权限:Security.allowDomain("js域名");JS端调用AS3函数时,需确保SWF的allowScriptAccess参数设置为always(HTML中:<embed allowScriptAccess="always">),若仍无法解决,可通过代理页面(将JS请求代理到SWF同域)或JSONP方式间接通讯。
Q2:ExternalInterface调用JS函数时,如何传递AS3的复杂对象(如自定义类实例)?
A:AS3的复杂对象(如自定义类实例)无法直接传递给JS,需先序列化为JSON字符串:
- AS3端:使用
JSON.stringify()将对象转为JSON(需引入com.adobe.serialization.json.JSON类),JS端通过JSON.parse()解析。 - 示例:
var user:Object = {name: "张三", age: 25}; var jsonStr:String = JSON.stringify(user); ExternalInterface.call("handleUserData", jsonStr);function handleUserData(jsonStr) { var user = JSON.parse(jsonStr); console.log(user.name); // 输出:"张三" }若需传递数组,同理使用JSON序列化,避免直接传递AS3的Array类型(JS可能无法识别)。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复