【问题标题】:Flash policy file not working (same domain, different port)Flash 策略文件不起作用(相同的域,不同的端口)
【发布时间】:2013-01-08 04:37:50
【问题描述】:

我很茫然。我不明白为什么 Flash 没有正确加载我的策略文件。我正在通过 Flash 调试器对此进行测试。

I've also tried from http://127.0.0.1:80/game (it sends a request to http://127.0.0.1:3014/socket.io/1/).
          Security.loadPolicyFile('xmlsocket://127.0.0.1:843');

          var r:URLRequest = new URLRequest();
          r.url = httpProtocal+"://" + domain + "/socket.io/1/?time=" + new Date().getTime();
          r.method = URLRequestMethod.POST;
          var ul:URLLoader = new URLLoader(r);
          ul.addEventListener(Event.COMPLETE, onDiscover);
          ul.addEventListener(HTTPStatusEvent.HTTP_STATUS, onDiscoverError);
          ul.addEventListener(IOErrorEvent.IO_ERROR , onDiscoverError);

错误:

> webSocketLog: policy file: xmlsocket://127.0.0.1:843 Error #2044:
> Unhandled securityError:. text=Error #2048: Security sandbox
> violation: file:///ude/game/bin-release/Game.swf cannot load data from
> http://127.0.0.1:3014/socket.io/1/?time=1359025067289.    at
> com.pnwrain.flashsocket::FlashSocket()

但这是可行的:

> echo -ne '<policy-file-request/>\0' | nc -v 127.0.0.1 843  

Connection to 127.0.0.1 843 port [tcp/*] succeeded!
<?xml version='1.0' ?>
<!DOCTYPE cross-domain-policy SYSTEM 'http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd'>
<cross-domain-policy>
    <allow-access-from domain='*' to-ports='*' />
</cross-domain-policy>

指定 crossdomain.xml 的绝对路径也不起作用。我可以在我的浏览器中加载这个文件。

> webSocketLog: policy file: http://127.0.0.1:843/crossdomain.xml
> Error #2044: Unhandled securityError:. text=Error #2048: Security
> sandbox violation: file:///ude/game/bin-release/Game.swf cannot load
> data from http://127.0.0.1:3014/socket.io/1/?time=1359025126138.  at
> com.pnwrain.flashsocket::FlashSocket()

即使这样也行不通(来自非常受欢迎的博客文章的解决方案):

import flash.system.Security; Security.allowDomain("http://127.0.0.1");

这是调试器策略文件日志:

> OK: Root-level SWF loaded:
> file:///ude/game/bin-release/Game.swf
> OK: Searching for <allow-access-from> in policy files to authorize
> data loading from resource at
> http://127.0.0.1:3014/socket.io/1/?time=1359026453454 by requestor
> from
> file:///ude/game/bin-release/Game.swf
> Error: [strict] Ignoring policy file at
> http://127.0.0.1:3014/crossdomain.xml due to missing Content-Type. 
> See http://www.adobe.com/go/strict_policy_files to fix this problem.
> Error: Request for resource at
> http://127.0.0.1:3014/socket.io/1/?time=1359026453454 by requestor
> from
> file:///ude/game/bin-release/Game.swf
> is denied due to lack of policy file permissions. Warning: HTTP
> response headers not available on this platform.  Strict policy file
> rules cannot be enforced. OK: Policy file accepted:
> http://127.0.0.1:843/crossdomain.xml

这里有趣的部分是OK: Policy file accepted 消息出现在错误之后,即使我正在调用:

Security.loadPolicyFile('http://127.0.0.1:843/crossdomain.xml');

URLRequest 之前。所以我将URLRequest 移到了setTimeout 中,现在日志显示:

> OK: Root-level SWF loaded:
> file:///ude/game/bin-release/Game.swf
> Warning: HTTP response headers not available on this platform.  Strict
> policy file rules cannot be enforced. OK: Policy file accepted:
> http://127.0.0.1:843/crossdomain.xml OK: Searching for
> <allow-access-from> in policy files to authorize data loading from
> resource at http://127.0.0.1:3014/socket.io/1/?time=1359028255268 by
> requestor from
> file:///ude/game/bin-release/Game.swf
> Error: [strict] Ignoring policy file at
> http://127.0.0.1:3014/crossdomain.xml due to missing Content-Type. 
> See http://www.adobe.com/go/strict_policy_files to fix this problem.

所以,它似乎已经很好地加载了 843 策略文件,但随后尝试加载端口 3014 策略文件(可能正在检查子策略文件?)。这只是一个 socket.io HTML 页面,上面写着“欢迎来到 socket.io”。由于这个原因,它似乎不应该失败..

我在调试器警报中得到了这个:

Error #2044: Unhandled securityError:. text=Error #2048: Security sandbox violation: file:///ude/game/bin-release/Game.swf cannot load data from http://127.0.0.1:3014/socket.io/1/?time=1359028255268.
    at MethodInfo-3642()
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at SetIntervalTimer/onTimer()
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()

非常感谢任何想法。谢谢!

【问题讨论】:

    标签: flash cross-domain-policy


    【解决方案1】:

    我不是政策文件的专家,但这看起来很可疑:

    错误: [strict] 忽略策略文件位于 http://127.0.0.1:3014/crossdomain.xml 由于缺少 Content-Type。 请参阅http://www.adobe.com/go/strict_policy_files 解决此问题。

    似乎策略文件被忽略,因为它没有或无效的 Content-Type 标头。

    来自Adobe:

    从版本 9,0,115,0 开始,Flash Player 将忽略任何未使用 Content-Type 值发送的 HTTP 策略文件,该值可确保文件是文本文件。 Flash Player 要求策略文件的 Content-Type 必须是以下之一:

    • text/* (any text type)
    • application/xmlapplication/xhtml+xml

    还有这个:

    如果您发现需要解决 Content-Type 问题,请务必同时参考 meta-policies 部分,因为选择元策略的常用方法是指定 @987654329 的特殊 Content-Type @ 用于所有策略文件,这可以同时解决两个问题 - 建立元策略和提供文本 Content-Type。

    还要检查服务器为什么 HTTP 响应标头不可用:

    警告:此平台上的 HTTP 响应标头不可用。严格的 无法强制执行策略文件规则。

    希望这会有所帮助。

    【讨论】:

    • 你好双脸!是的,但是在我明确指定在哪里找到策略文件之后,该错误来自 HTTP 请求。哪个已加载。我理解为什么它会尝试为那个 HTTP URL 加载一个,它可能有一个子策略文件。因为 Content-Type 错误,所以忽略了第一个策略文件?
    • 好吧,我不确定,但也许您需要从端口 843 提供服务的套接字主策略文件。似乎现在您必须为套接字连接提供特殊的策略文件。看看这里adobe.com/devnet/flashplayer/articles/socket_policy_files.html
    • &lt;?xml version="1.0"?&gt; &lt;!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd"&gt; &lt;!-- Policy file for xmlsocket://socks.example.com --&gt; &lt;cross-domain-policy&gt; &lt;!-- This is a master-policy file --&gt; &lt;site-control permitted-cross-domain-policies="master-only"/&gt; &lt;allow-access-from domain="*" to-ports="*" /&gt; &lt;/cross-domain-policy&gt;
    【解决方案2】:

    成功连接和策略验证的关键是:

    1) 在与您的 socket.io 脚本相同的文件夹中有一个 crossdomain.xml 文件。

    2) 通过 http 在运行 socket.io 服务器的同一 host:port 中提供此 crossdomain.xml。

    3) 要实现这一点,您需要安装除 socket.io 之外的 express 框架。使用 express 和 socket.io,您可以通过 http 和连接套接字同时在同一端口上提供 crossdomain.xml。

    4)通过这种方法,flash可以在最初寻找这个策略文件的位置(同一个host:port)找到crossdomain.xml,避免了手动从flash加载策略文件(可以禁用loadPolicyFile)

    应该是这样的:

    var app = require('express')();
    var server = require('http').createServer(app);
    var io = require('socket.io').listen(server);
    
    app.get('/crossdomain.xml', function (req, res) {
      console.log("request ... " + __dirname);
      res.sendfile(__dirname + '/crossdomain.xml');
    });
    
    server.listen(port, "ip");
    console.log("socket.io server started");
    

    【讨论】:

      猜你喜欢
      • 2014-05-26
      • 1970-01-01
      • 2011-02-05
      • 2013-10-04
      • 2012-08-11
      • 2014-08-06
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      相关资源
      最近更新 更多