Flash与JavaScript通信的核心是借助ExternalInterface接口实现双向调用,但Adobe已在2020年停止Flash支持,目前主流方案是迁移至HTML5的Web API。 对于仍在维护遗留Flash项目的开发者,理解这一通信机制仍具实际价值,本文将从原理、实现、兼容性、性能到迁移路径,完整拆解Flash与JS通信的全貌。
Flash与JS交互方法的演进
Flash与JavaScript的交互方法经历了从早期笨拙的fscommand到成熟稳定的ExternalInterface的进化,行业共识认为,ExternalInterface是历史上最可靠、使用最广泛的通信方式。
从fscommand到ExternalInterface
- fscommand:在Flash 6及之前版本中,通过
fscommand函数向宿主环境发送指令,但只能传递字符串,且回调方式受限。 - ExternalInterface:Flash 8引入,支持双向、带参数、返回值的调用,类型自动转换,成为长期标准。
ExternalInterface的工作机制
ExternalInterface利用浏览器插件桥接技术,在Flash播放器与JavaScript引擎之间建立一条双向通道,Flash端通过ExternalInterface.call()调用JS函数,JS端通过注册的回调函数调用Flash内部方法。
浏览器对通信的支持区别
不同浏览器对Flash插件的嵌入方式不同,影响通信的稳定性:
- IE浏览器:使用ActiveX控件,JS通过
document.getElementById或window对象获取Flash引用。 - Chrome、Firefox旧版:使用NPAPI插件,通信方式类似但对象获取细节略有差异。
- 兼容处理需同时考虑
<object>和<embed>标签,并设置allowScriptAccess="always"。
Flash调用JavaScript函数的具体步骤
在需要从Flash触发JS操作的场景中,ExternalInterface.call()是最直接的方法,以下是一个标准操作流程。
环境准备
- Flash项目需导入
flash.external.ExternalInterface类。 - HTML中嵌入的Flash对象需设置
allowScriptAccess="always",否则通信会被安全沙箱阻止。
代码实现
在AS3中调用JS函数:
import flash.external.ExternalInterface;
// 调用JS函数,无返回值
ExternalInterface.call("alert", "Hello from Flash");
// 调用JS函数并获取返回值
var result:String = ExternalInterface.call("getUserData", "id123");
JS端对应函数:
function getUserData(id) {
return '{"name":"test","id":"' + id + '"}';
}
注意事项
- 参数类型自动转换:String、Number、Boolean、Array、Object均可直接传递,但Date和自定义类需序列化。
- 返回值为类型,需在AS3中做类型转换。
- 调用时机:必须在Flash完成初始化后调用,避免在
preloader阶段执行。
JS调用Flash函数的使用场景
JS驱动Flash内部逻辑,常见于页面控制动画、视频播放、数据同步等场景,Flash需先注册回调函数。
注册回调函数
在AS3中:
ExternalInterface.addCallback("playVideo", playVideo);
ExternalInterface.addCallback("pauseVideo", pauseVideo);
function playVideo():void {
videoPlayer.play();
}
function pauseVideo():void {
videoPlayer.pause();
}
JS端调用
var flashObj = document.getElementById("myFlash");
flashObj.playVideo();
常见场景
- 页面按钮控制Flash暂停/播放。
- 表单数据提交前通过Flash验证。
- 实时数据更新推动Flash图表刷新。
Flash JS通信跨浏览器兼容方案
由于Flash插件在不同浏览器中的实现差异,兼容性曾是开发中的主要痛点,以下方案可以显著提升通信成功率。
兼容性处理清单
- 使用
<object>和<embed>双标签嵌入,确保所有浏览器能找到Flash对象。 - 设置
allowScriptAccess="always",避免安全限制。 - 在JS中获取Flash对象时,采用多种方式兜底:
function getFlashObject(id) {
if (document.getElementById(id)) return document.getElementById(id);
if (window[id]) return window[id];
if (document.embeds && document.embeds[id]) return document.embeds[id];
return null;
}
跨域通信限制
- 如果Flash文件与HTML文件不在同一域,需在Flash文件所在域根目录放置
,允许跨域脚本访问。crossdomain.xml
- 通信时,
allowScriptAccess需设置为always,并配合allowNetworking="all"。
已知问题与规避
- 在Chrome中,Flash被默认禁用,需用户手动开启,这导致通信可能无法正常建立。
- 在移动端,Flash从未被支持,因此通信完全不可用。
Flash与JavaScript通信实例分析
通过一个完整实例展示双向通信流程:Flash动画中的按钮被点击时,调用JS弹出提示框;JS可控制Flash跳转到指定帧。
实例需求
- 在Flash中放置一个按钮,点击后让JS显示“Button clicked”。
- 在HTML中放置一个输入框,输入帧数,点击按钮让Flash跳转。
Flash端代码
import flash.external.ExternalInterface;
btn.addEventListener(MouseEvent.CLICK, onBtnClick);
function onBtnClick(e:MouseEvent):void {
ExternalInterface.call("showAlert", "Button clicked");
}
ExternalInterface.addCallback("gotoFrame", gotoFrame);
function gotoFrame(frameNum:int):void {
gotoAndPlay(frameNum);
}
HTML端代码
function showAlert(msg) {
alert(msg);
}
function sendToFlash() {
var frame = document.getElementById("frameInput").value;
var flashObj = getFlashObject("myFlash");
if (flashObj) {
flashObj.gotoFrame(parseInt(frame));
}
}
测试要点
- 确保Flash安全设置允许通信。
- 在本地测试时,需将Flash文件加入受信任位置,或通过
localhost访问。 - 通信时参数类型需匹配,AS3的
int对应JS的Number。
性能与安全考量
Flash与JS通信并非零成本,尤其在频繁调用或传输大量数据时,需关注性能瓶颈。
性能表现
- 每次通信都会触发插件与浏览器的桥接,单次调用延迟通常为1-5毫秒。
- 每秒超过100次调用时,可能对页面响应造成可见影响。
- 批量传输数据时,建议将数据打包为JSON字符串,一次调用传输,减少通信次数。
安全限制
- Flash Player的沙箱机制限制外部脚本访问,需正确配置
allowScriptAccess和
crossdomain.xml。 - 业内专家指出,将
allowScriptAccess设为always会带来跨站脚本风险,需确保Flash文件来源可信。 - 避免在Flash中直接操作敏感数据,通信内容如被拦截可被攻击者利用。
迁移到现代替代方案
随着Flash被彻底淘汰,依赖Flash与JS通信的项目需要迁移到Web标准技术。
备选技术对比
| 技术 | 优势 | 劣势 |
|---|---|---|
| WebSocket | 全双工、低延迟、适合实时应用 | 需要服务器支持,不适合简单通信 |
| PostMessage | 跨窗口/iframe通信,语法简单 | 仅限同源或明确指定目标窗口 |
| 自定义事件 | 兼容性好,与DOM紧密结合 | 只适用于同一页面内的模块通信 |
迁移步骤建议
- 分析现有通信接口,识别Flash端所有
ExternalInterface.call和ExternalInterface.addCallback调用。 - 将Flash端的逻辑重构为JavaScript函数,使用
addEventListener和dispatchEvent模拟事件驱动。 - 如果涉及动画或图形,使用Canvas或WebGL替换Flash渲染。
结束语
Flash与JS通信虽然已退出主流,但其设计思想通过桥接层实现跨环境调用对理解现代Web API仍有启发,对于仍在维护的遗留项目,掌握ExternalInterface的使用仍有必要,但长远来看,尽早迁移才是最佳选择。
Q&A:Flash与JS通信常见问题
问:Flash与JS通信是否安全?
答:只要正确设置allowScriptAccess为always并限制跨域,通信本身是安全的,但Flash Player已停止安全更新,存在已知漏洞,不应在新项目中使用。
问:Flash停止支持后,ExternalInterface还能用吗?
答:已安装的Flash Player仍可运行,但主流浏览器均默认禁用Flash,用户需手动开启,实际应用场景已极少,建议尽快迁移。
问:Flash AS3与JS通信时,参数类型如何匹配?
答:ExternalInterface自动处理常见类型转换,如String、Number、Boolean、Array等,复杂对象建议使用JSON字符串传递,这是Flash AS3与JS通信中需要注意的细节。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/586465.html




