萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 軟體知識 >  >> 影像處理 >> Flash 教學

Flash Player 在多標籤瀏覽器中的「偽沙箱」問題分析與解決方案

Flash Player 的安全沙箱機制規定:不同域的 SWF 與 HTML 頁面互相訪問需雙向授權(Security.allowDomain("*") + allowScriptAccess="always")。但在基於 IE 內核的多標籤瀏覽器(傲遊、360、騰訊瀏覽器等)中,刷新頁面時仍會拋出安全沙箱錯誤,導致 ExternalInterface 通信失效。本文深度分析根因並提供工程級解決方案。

問題現象

測試頁面

  • Chrome、Firefox、原生 IE6/7/8:正常
  • IE 內核多標籤瀏覽器:首次載入正常,刷新後失效
  • 錯誤堆疊:SecurityError: Error #2060: 安全沙箱衝突: ExternalInterface 調用者 ... 不能訪問 ...

錯誤堆疊

根因分析:瀏覽器緩存導致的 allowScriptAccess 失效

Flash 代碼示例:

package {
    import flash.display.Sprite;
    import flash.external.ExternalInterface;
    import flash.system.Security;
    import flash.text.TextField;

    public class Main extends Sprite {
        public function Main():void {
            var tf:TextField = new TextField();
            tf.text = 'flash ready';
            tf.autoSize = 'left';
            addChild(tf);
            Security.allowDomain("*");
            start();
        }

        private function start():void {
            ExternalInterface.call("alert", "Hi, flash is ready!");
            ExternalInterface.addCallback('drawCircle', drawCircle);
        }

        private function drawCircle():void {
            // 繪圖邏輯...
        }
    }
}

驗證緩存假設

  • 為 SWF URL 添加隨機參數(如 test.swf?t=12345)強制繞過緩存
  • 結果:問題消失,確認瀏覽器緩存導致 allowScriptAccess 配置失效

解決方案對比

最佳實踐:延遲 500ms 初始化

public class Main extends Sprite {
    public function Main():void {
        // ... 初始化 UI ...
        Security.allowDomain("*");
        // start();  // 直接調用會失敗
        setTimeout(start, 500); // 關鍵:延遲 500ms
    }

    private function start():void {
        ExternalInterface.call("alert", "Hi, flash is ready!");
        ExternalInterface.addCallback('drawCircle', drawCircle);
    }
    // ...
}

為什麼是 500ms?

  • 經驗值:阿里巴巴中文站所有需 JS 通信的 Flash 應用均採用 500ms
  • 太短(<200ms):低效能電腦仍會失敗
  • 太長(>1000ms):用戶感知明顯延遲
  • 500ms 平衡了兼容性與體驗

額外收益:修復 IE6 stage.stageWidth 為 0 的 Bug

  • IE6 中 Flash 初始化時 stage.stageWidth 常返回 0
  • 延遲初始化同樣能讓 stage 尺寸正確就緒
  • 一石二鳥

工程建議

  1. 封裝通用基類 DelayedInitSprite,內建延遲邏輯
  2. 所有需 ExternalInterface 的專案繼承該基類
  3. 提供配置參數覆蓋延遲時間(預設 500ms)
  4. 加載階段顯示友好 Loading 動畫,掩蓋延遲體感

未解之謎與展望

根本原因在於 IE 內核多標籤瀏覽器的緩存機制與 Flash Player 初始化時序的競態條件。Adobe 官方未給出修復,瀏覽器廠商亦無動靜。若有更優雅方案(如監聽特定 JS 事件觸發初始化),歡迎技術社群共同探討。

copyright © 萬盛學電腦網 all rights reserved
方案原理優點缺點
SWF URL 加隨機數/時間戳繞過瀏覽器緩存簡單有效增加伺服器壓力,頁面載入永遠慢
延遲初始化(推薦)延後 ExternalInterface.addCallback 執行時機零額外請求,用戶無感,阿里巴巴生產環境驗證需經驗調優延遲時間