【问题标题】:Why does the Flash Player throw a sandbox error in this case?为什么 Flash Player 在这种情况下会引发沙盒错误?
【发布时间】:2010-12-15 03:11:30
【问题描述】:

在连接到 Java (1.5) 服务器上的 Socket 后,我​​收到 Flex 3 沙盒错误 #2048。服务器代码都是我的,即不在 Apache 下运行。 Flash Player 10.0 r32。

顺序如下……

1 Java 服务器启动,在端口 843 上侦听策略文件请求,在端口 45455 上侦听我的其他请求。

2 由 Apache 服务的 Flex 客户端(尽管如果我从文件系统运行它会得到相同的结果),在 host:45455 上建立了套接字连接。

3 Flash Player 从端口 843 请求策略文件。这是新安全设置查找主文件的标准行为。无论是否指定了不同的策略文件,都会发生这种情况。

4 我通过端口 843 从 Java 提供以下 XML:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
</cross-domain-policy>

5 播放器将以下内容写入调试策略日志...

OK: Root-level SWF loaded: http://localhost/bst/BasicSocketTest.swf
OK: Searching for <allow-access-from> in policy files to authorize data loading from resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf
OK: Policy file accepted: xmlsocket://192.168.2.3:843
OK: Request for resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf is permitted due to policy file at xmlsocket://192.168.2.3:843

6 我使用writeUTFBytes()flush() 在端口45455 上从客户端向服务器发送一条文本消息(这是我自己的自制消息协议,并且在每一端都正确处理)

REG/REGISTER;simon;Si

7 Java 服务器线程监听 45455 端口响应

REG:0/REGISTER:SUCCESS;simon;Si

8 Flex 客户端收到一个 ProgressEvent 并且我绑定到套接字的事件侦听器被调用。我处理消息(将其写入屏幕上的文本框)

9 Flash播放器抛出2048沙盒错误,socket断开!这是消息被成功接收和处理之后。事实上,大约是 12 秒后。没有其他东西通过套接字起作用。

我尝试在 Flex 客户端中通过调用 Security.loadPolicyFile() 显式加载策略文件,但新播放器安全性的实际情况是它基本上被忽略了。这些步骤是在发生套接字 i/o 操作之前不会发送策略请求。此时播放器总是首先去端口 843 寻找主策略文件。如果它找到一个,并且它是允许的,它就不会继续前进。

我尝试了多种终止策略文件和策略文件内容的替代方法,包括故意错误以查看 Flash Player 是否处于唤醒状态。

我看不出为什么会抛出 2048。我在指定的主安全端口上准确地提供了一个套接字策略文件,播放器本身将其记录为正确的。然后套接字成功地从服务器发送和接收一条消息,其内容可用于我的代码。

有人知道为什么会发生这种情况吗? Flash Player 错误?

PS 不要告诉我使用 BlazeDS 或 LCDS 或 Granite 或其他东西作为服务器,我正在寻找解决此问题的方法,不是重新设计。请不要让我改用 XMLSocket - 我试过了,得到了完全相同的结果。我已经仔细而慎重地选择了我的架构,并且我想要一个二进制套接字。

编辑 针对 James Ward 在评论中的请求,以下是完整的错误消息:

Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

我有一个精简的测试客户端,它对每个套接字事件都有一个处理程序,并向屏幕输出一条消息。这是它显示的内容:

RequestPolicy: 192.168.2.3:843
Create Socket: 192.168.2.3:45455
Connect: [Event type="connect" bubbles=false cancelable=false eventPhase=2]
Sending: REG/REGISTER;simon.palmer@gmail.com;Si
Receiving: REG:0/REGISTER:SUCCESS;simon.palmer@gmail.com;Si/
Close: [Event type="close" bubbles=false cancelable=false eventPhase=2]
Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

成功接收到服务器的响应后立即触发关闭事件,但是直到大约 20 秒后才会出现错误 #2048。如果我尝试在关闭之后但在错误之前发送更多消息,则 Flash Player 会引发无效的套接字异常。

我有 logged a bug at Adobe 关于这个。

如果有人感兴趣,我可以提供客户端和服务器的完整源代码。

【问题讨论】:

  • 写入闪存日志或策略文件日志的更多详细信息?如果是这样,您可以添加确切的消息吗?
  • flashlog 中有一条消息说正在加载 swf,但这就是策略日志,我已经逐字显示了整个内容。
  • 你能把整个错误信息贴出来吗?
  • 你能把你的测试源代码上传到FP-3302的bug吗?
  • @James,完成。我已将我的服务器代码和我可以制作的最简单的客户端放在一个 zip 文件中,并将其附加到问题中。

标签: apache-flex flash sockets sandbox


【解决方案1】:

我一直在本地对此进行测试,在套接字关闭之前一切似乎都运行良好。套接字不应该关闭吗?消息发送到 Flex 客户端后,Java 代码会:

_in.close();
_out.close();
_socket.close();

然后,Flex 客户端在下次尝试与套接字通信时会遇到沙盒违规。如果我再次创建一个新的套接字连接,那么发送和接收工作正常,然后关闭。但是大约一分钟后,我又遇到了一个沙盒违规行为。我想知道 Flash 是否正在尝试 ping 套接字并且由于它已关闭它会引发沙盒冲突?

【讨论】:

  • _in 和 _out 只是应该关闭的打印流,但 _socket 是 SocketServer 返回的 TCP 套接字,侦听端口为 843。我将注释掉所有 closes,看看会发生什么.非常感谢您的关注。
  • 进步!我不再收到沙盒错误,但套接字也不再起作用,因此通过它发送的第二条和后续消息不会到达服务器。我正在进一步调查,但这感觉像是向前迈出了一步。谢谢詹姆斯。
  • 出于某种原因,即使我注释掉了 _socket.close() 行,我仍然会收到一个关闭事件。不知道为什么会关闭。奇怪。
【解决方案2】:

您是否尝试过添加 allow-http-request-headers-from 元素?

<allow-http-request-headers-from domain="*" headers="*" />

或者为 allow-access-from 元素指定实际端口而不是 *?

<allow-access-from domain="*" to-ports="843,45455" />

【讨论】:

【解决方案3】:

类似的问题here 表示 localhost 没有被解析为 127.0.0.1。

您可以尝试切换到 IP 地址,看看是否有帮助。

【讨论】:

  • 感谢您的建议,但是我在绑定套接字时只使用IP地址,因此其他线程中的localhost解析不适用
  • 是的,但输出日志显示localhost/bst/BasicSocketTest.swf 另一种测试方法是将其放在某个公共服务器上并测试该 url 而不是从本地主机。
【解决方案4】:

除了 yoru crossdomain.xml 之外,您还可以在代码中使用 Security 类进一步尝试一些事情

试试:

Security.allowDomain("*")
Security.allowInsecureDomain("*")

或者,如果您从 aporoved 允许主机之外的外部服务器加载:

Security.allowDomain(loader.contentLoaderInfo.url)

然后慢慢将其重新打开,直到遇到错误。

确保您可以直接访问策略文件,并且该端口上没有运行任何块或其他应用程序。通常,当我运行套接字时,我会高于 5000,以确保没有任何东西占用端口。或者尝试几个不同的端口。

作为一个简单的检查,确保您将其命名为 crossdomain.xml,并且它都是小写的。我让程序员拔掉头发,结果证明是这个原因。

【讨论】:

  • 感谢代码建议,我尝试将两者都添加到我的代码中,但我得到了相同的沙箱错误。我的服务器成功打开了 843 和 45455,所以我没有任何端口阻塞问题。正如我在问题中所说,第一条消息通过,除非套接字正常工作,否则不会发生。另外我没有使用 HTTP,因此 crossdomain.xml 无关紧要,因为播放器正在端口 843 上寻找套接字主策略文件。这有效,我提供了一个开放的策略文件。我仍然收到沙盒错误。 adobe.com/devnet/flashplayer/articles/fplayer9_security_04.html
【解决方案5】:

尝试在 xml 结束标记“/>”之前放置一个空白,就像在 dan_nl 建议中一样,例如:

别笑,我刚刚解决了一个和你非常相似的问题(而且它真的看起来像一个解析错误恕我直言)

【讨论】:

    【解决方案6】:

    任何机会...这是否发生在 Windows Vista 上? IP 地址是否指定为主机名?如果是这样,请参阅this

    或者它可能在分析器处于活动状态时发生?如果是这样,请参阅this

    【讨论】:

    • 谢谢,但不行,XP。 @Phil Hayward 也发布了您的第一个链接。我不能肯定这不会在公共互联网上消失,我正要租用公共服务器来试用它 - 一项昂贵的错误调查。没有性能分析器。
    【解决方案7】:

    发送策略文件时,服务器应始终在策略 xml 之后发送一个零字节。从上面的描述中并不清楚是否发送了零字节,这最终可能会混淆Flash播放器。

    【讨论】:

    • 我知道空终止字节,并尝试过没有任何效果。但是,我在其他一些更改中尝试了它,所以也许我会再试一次。谢谢你的回答。
    【解决方案8】:

    这可能会或可能不会帮助您,但我们遇到了类似的问题。我们收到了安全错误,但它不一致。我构建了前端,并与一位处理用 PHP 编写的 Socket 的开发人员一起工作。问题似乎是确实存在竞争条件,Flash 会在接收策略文件之前尝试连接到套接字。因此,在前端,我在安全错误处理程序中创建了一个重试,它将在放弃之前运行一定次数,还将超时从默认的 20 秒设置为 6 或 8。它通常会在第 2 次捕获尝试一下,这确实有帮助,但有时需要 8-10 秒才能连接,这不是最佳解决方案。

    在我的搜索中发现了一些链接,这个链接说的是关于在服务器上设置延迟,第 7 个帖子: http://projectdarkstar.com/forum/?action=printpage;topic=1134.0

    最后,我们从这篇 Adob​​e 文章中下载并使用了 Python 策略文件服务器,它一直在完美运行,我无法解释为什么,我不是服务器专家,但可能值得一试:

    好的,因为我是新用户,所以我只能发布 1 个超链接,奇怪。搜索“设置套接字策略文件服务器”,它应该会出现,Adobe 网站上的那篇文章中有示例文件。

    【讨论】:

    • 这是一个非常有用的线索,非常感谢。我会稍微改变一下我的服务器代码来尝试其中的一些事情。如何更改超时?
    • 希望你需要 Flash 10,似乎是它被引入的时候:help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/net/…
    • 我在该线程上尝试了与 OP 相同的操作,即添加延迟并确保套接字在服务器端关闭,我得到的时间略有不同,但最终结果相同。我应该将 Flash 播放器版本放在原始问题中 - 感谢您指出这一点,我会进行编辑。
    【解决方案9】:

    我认为 James Ward 是对的——我现在正在使用 Sockets,前几天我遇到了这个问题。我发现一篇帖子建议如果在调度 COMPLETE 事件时 Flash 客户端没有关闭 Socket,这可能会导致您看到的错误。我添加了代码以在 COMPLETE 上关闭客户端 Socket,到目前为止一切正常。

    【讨论】:

    • 这很有趣,但有点令人困惑。那么您是否为每个请求创建一个新的客户端套接字?我正在捕获从客户端套接字发出的所有事件,但我根本没有收到 COMPLETE 事件 - 事实上我无法完全确定可能是哪个事件,你能给出准确的事件细节吗?我处理套接字触发的 ProgressEvent.SOCKET_DATA 事件的数据。
    猜你喜欢
    • 2021-06-19
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多