在我最近开发的一个较大的项目中,当尝试从AS3向Javascript发送Base64编码的数据时,遇到了AS3 ExternalInterface
的以下奇怪行为。我将代码简化为如下所示的最简单的版本:TestSWF.as
文件:
package {
import flash.external.ExternalInterface;
import flash.display.Sprite;
public class TestSWF extends Sprite {
public function callTestSWF():String {
var strToRet:String = '/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+';
trace(strToRet);
return strToRet;
}
public function TestSWF() {
ExternalInterface.addCallback("CallTestSWF", callTestSWF);
}
}
}
该文件使用Flex-SDK 4.6使用
mxmlc -output test.swf -compiler.omit-trace-statements=false -static-link-runtime-shared-libraries -- TestSWF.as
相应的
index.html
文件是:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test SWF</title>
</head>
<body style="font-family:sans-serif;">
<script>
function getStr() {
var flash = document.getElementById('swfObj');
var outText = flash.CallTestSWF();
document.getElementById('fromFlash').innerHTML = outText;
}
</script>
<input type="button" onclick="getStr();" id="sendToFlash" value="Call Flash"/>
<hr/>
<pre id="fromFlash">---</pre>
<hr/>
<embed id="swfObj" src="test.swf">
</body>
</html>
现在,当此
index.html
由Web服务器公开并且客户端浏览器装有Flash Player的调试版本(v。20.0)时,我得到一个非常奇怪的警告WARNING: For content targeting Flash Player version 14 or higher, ExternalInterface escapes strings using JSON conventions. To maintain compatibility, content published to earlier Flash Player versions continues to use the legacy escaping behavior.
值得一提的是,任何地方都没有使用
JSON
。请注意,从AS3返回的字符串包含Base64代码中使用的完整字符集。当删除“ /
”时,该警告消失。这是错误还是对此令人讨厌的行为的解释是什么?欢迎发表任何评论。
最佳答案
每当您通过ExternalInterface
传递曾经以不同方式转义的特殊字符时,就会发生这种相当烦人的警告。在大多数情况下,您可以忽略它。
详细说明:在Flash Player 14之前,用于转义通过ExternalInterface
传递的字符串的内部方法存在很多问题(例如JS注入漏洞),导致开发人员提出了正则表达式的解决方法。当转义行为在Flash Player 14中更改(使用JSON约定)时,它可能会破坏许多开发人员的先前修复程序,因此,他们不只是发布重大更改,而是选择支持针对较早播放器的SWF的旧式转义行为,并发出警告。当字符串通过包含字符的ExternalInterface
传递时,开发人员可能会尝试以某种奇怪的方式进行转义以支持旧版转义行为,这会破坏新行为。换句话说,此警告并不是说您做错了什么,而是让您意识到Flash Player中针对所使用的某些字符串而发生了更改的行为。如果您的字符串按预期工作,则警告不是问题,您无需执行任何操作。这就是为什么我说这很“烦人”。基本上,这是“旧版API警告”,除了API相同之外,它是现有API的行为,可能具有您需要了解的旧行为。
如果您在互联网上搜索,那么到处都会发现这个故事的片段。
如果您确实希望警告消失,则可以对特殊字符进行编码。以我的经验,最简单的方法是在另一端使用encodeURIComponent
和decodeURIComponent
:
HTML:
<script>
function getStr() {
var flash = document.getElementById('swfObj');
var outText = decodeURIComponent(flash.callTestSWF());
document.getElementById('fromFlash').innerHTML = outText;
}
</script>
AS3:
public function callTestSWF():String {
var strToRet:String = encodeURIComponent('/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+');
trace(strToRet);
return strToRet;
}
或者您可以使用正则表达式,但是就您个人而言,我会忽略警告,因为您知道代码可以正常工作,而不会引入一些易碎的正则表达式。