Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Нарушение изолированной среды (http://www.flasher.ru/forum/showthread.php?t=194802)

Vreden 22.02.2013 17:50

Нарушение изолированной среды
 
Код:

Error #2044: Необработанный SecurityErrorEvent:. text=Error #2048: Нарушение изолированной среды: http://cs405122.userapi.com/u7907811/4da01a287.zip не может загрузить данные из http://vk.com/images/camera_b.gif.
При загрузке информации о пользователях используя api вконтакте, получаю url аватаров пользователей.
Если аватар есть, то все они из зоны userapi.com и загружаются нормально без SecurityErrorEvent, но если у пользователя нет аватара, то api возвращает http://vk.com/images/camera_b.gif. Т.е. это изображение из чужого для swf домена и возникает ошибка SecurityErrorEvent

Использую Loader с LoaderContext по всем правилам, на продуктиве ошибка воспроизводится постоянно.

Код AS3:

var context:LoaderContext;
 
if (Security.sandboxType != Security.LOCAL_TRUSTED)
        context = new LoaderContext(true, ApplicationDomain.currentDomain, SecurityDomain.currentDomain);
 
loader.load(new URLRequest(__currentImageUrlLoad), context);

В чем может быть проблема?

caseyryan 22.02.2013 18:05

Цитата:

В чем может быть проблема?
То, в чем проблема подробно описано в тексте ошибки.
А избегается так:
Код AS3:

try {
    loader.load(new URLRequest(__currentImageUrlLoad), context);
} catch (e:Error) {}

и к загрузчику нужно добавить слушатель события SecurityErrorEvent

Vreden 22.02.2013 20:15

Мне нужна помощь не в обработке этой ошибки, а в ее устранении

AlexLucas 22.02.2013 21:29

Ну, как вариант, в catch'e вставляйте свой дефолтный аватар.

Vreden 22.02.2013 22:32

Как вариант, но самый последний.
Мне необходимо устранить нарушение изолированной среды, а не реализовать ее следствие.

yasha005 23.02.2013 00:46

Цитата:

Сообщение от Vreden (Сообщение 1121934)
Как вариант, но самый последний.
Мне необходимо устранить нарушение изолированной среды, а не реализовать ее следствие.

Как вариант в обход файла политик и в обход изолированной среды можно провернуть вот такой чит, реализованный в методе EventFunctionComplete:

Код AS3:

package lib_loader
{
        import flash.net.URLRequest;
        import flash.display.Loader;
        import flash.net.URLRequestMethod;
        import flash.events.IOErrorEvent;
        import flash.events.SecurityErrorEvent;
        import flash.errors.IOError;
        import flash.events.ProgressEvent;
        import flash.events.Event;
        import flash.events.ErrorEvent;
        import flash.system.ApplicationDomain;
        import flash.system.LoaderContext;
        import flash.utils.ByteArray;
 
        public class LibContentLoaderNoPolicyBytes implements ILibLoader
        {
                // Адрес, откуда необходимо загрузить компонент
                private var urlFrom:String;
                // Передаваемые параметры методом POST
                private var dataFrom:Object;
 
                // Метод, выполняемый при наступлении события успешной загрузки
                private var eventFunctionComplit:Function;
                // Метод, выполняемый во время загрузки
                private var eventFunctionProgress:Function;
                // Метод, выполняемый при ошибке загрузки
                private var eventFunctionError:Function;
                // Метод, выполняемый при отмене загрузки
                private var eventFunctionUndo:Function;
 
                // Флаг выполнения загрузки
                private var eventListener:Boolean = false;
                // Объект передаваемых параметров загрузки
                private var requestLoader:URLRequest;
                // Объект загрузки
                private var objectLoader:Loader;
                // Флаг отмены загрузки
                private var flagUnload:Boolean = false;
 
 
 
                /*////////////////////////////////////////////////////////////
 
                        Загрузка двоичных данных, таких как изображения
 
                ////////////////////////////////////////////////////////////*/

 
                public function LibContentLoaderNoPolicyBytes()
                {
                        // constructor code
                }
 
                // Установить параметры объекта
                public function set SetParam(paramObject:Object):void
                {
                        if(paramObject is Object)
                        {
                                // Адрес, откуда необходимо загрузить компонент
                                if(paramObject.urlLoc is String)
                                {
                                        this.urlFrom = paramObject.urlLoc;
                                }
 
                                // Передаваемые параметры методом POST
                                if(paramObject.dataLoc is Object)
                                {
                                        this.dataFrom = paramObject.dataLoc;
                                }
 
                                // Метод, выполняемый при наступлении события успешной загрузки
                                if(paramObject.functionComplitLoc is Function)
                                {
                                        this.eventFunctionComplit = paramObject.functionComplitLoc;
                                }
 
                                // Метод, выполняемый во время загрузки
                                if(paramObject.functionProgressLoc is Function)
                                {
                                        this.eventFunctionProgress = paramObject.functionProgressLoc;
                                }
 
                                // Метод, выполняемый при ошибке загрузки
                                if(paramObject.functionErrorLoc is Function)
                                {
                                        this.eventFunctionError = paramObject.functionErrorLoc;
                                }
 
                                // Метод, выполняемый при отмене загрузки
                                if(paramObject.functionUndoLoc is Function)
                                {
                                        this.eventFunctionUndo = paramObject.functionUndoLoc;
                                }
 
                                // Начать/остановить загрузку true/false
                                if(paramObject.startLoc is Boolean)
                                {
                                        if(this.eventListener && !paramObject.startLoc)
                                        {
                                                this.flagUnload = true;
                                                this.objectLoader.unload();
                                        }
                                        this.EventListener = paramObject.startLoc;
                                }
 
 
                        } // Конец объекта
                } // Конец метода установки параметров
 
                // Подключение или отключение слушателей событий
                private function set EventListener(flagEvent:Boolean):void
                {
                        if(this.eventListener != flagEvent)
                        {
                                if(this.eventListener = flagEvent)
                                {
                                        // Подключение слушателей событий
                                        this.AddEventListener();
                                }
                                else
                                {
                                        // Отключение слушателей событий
                                        this.RemoveEventListener();
                                }
                        }
                }
 
                private function Builder():void
                {
                        this.requestLoader = new URLRequest();
                        this.objectLoader = new Loader();
                }
 
                private function Destroy():void
                {
                        this.EventListener = false;
                        this.objectLoader = null;
                        this.requestLoader = null;
                        this.urlFrom = null;
                        this.dataFrom = null;
                }
 
 
                private function AddEventListener():void
                {
                        this.Builder();
                        if(this.dataFrom is Object)
                        {
                                this.requestLoader.method = URLRequestMethod.POST;
                                this.requestLoader.data = this.dataFrom;
                        }
 
                        if((this.urlFrom is String) && this.urlFrom.length)
                        {
                                this.requestLoader.url = this.urlFrom;
                                try
                                {
                                        this.objectLoader.load(this.requestLoader);
                                }
                                catch (e:ArgumentError)
                                {
                                        this.FunctionError(e.message);
 
                                }
                                catch (e:SecurityError)
                                {
                                        this.FunctionError(e.message);
 
                                }
                                catch (e:IOError)
                                {
                                        this.FunctionError(e.message);
 
                                }
                                catch (e:Error)
                                {
                                        this.FunctionError(e.message);
 
                                }
                                finally
                                {
                                }
 
                                this.objectLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR , this.EventFunctionError);
                                this.objectLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR , this.EventFunctionError);
                                this.objectLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS , this.EventFunctionProgress);
                                this.objectLoader.contentLoaderInfo.addEventListener(Event.INIT , this.EventFunctionInit);
                                //this.objectLoader.contentLoaderInfo.addEventListener(Event.COMPLETE , this.EventFunctionComplete);
 
 
 
                        }
                        else
                        {
                                var e:Error = new Error('url is null');
                                this.FunctionError(e.message);
                        }
                }
 
                private function RemoveEventListener():void
                {
                        this.objectLoader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR , this.EventFunctionError);
                        this.objectLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR , this.EventFunctionError);
                        this.objectLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS , this.EventFunctionProgress);
                        this.objectLoader.contentLoaderInfo.removeEventListener(Event.INIT , this.EventFunctionInit);
                        if(this.flagUnload)
                        this.objectLoader.contentLoaderInfo.addEventListener(Event.UNLOAD , this.EventFunctionUndo);
 
 
                }
 
                ////////////////////////////////////////////////////////////
 
                private function EventFunctionUndo(e:Event):void
                {
                        this.flagUnload = false;
                        this.objectLoader.contentLoaderInfo.removeEventListener(Event.UNLOAD , this.EventFunctionUndo);                       
                        if (this.eventFunctionUndo is Function) this.eventFunctionUndo();
                        this.Destroy();
                }
 
                ///////////////////////////////////////////////////////////
 
                private function EventFunctionComplete(e:Event):void
                {
 
                        this.objectLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE , this.EventFunctionComplete);
                        var objectLoaderLocal:Loader = new Loader();
                        objectLoaderLocal.loadBytes(this.objectLoader.contentLoaderInfo.bytes, new LoaderContext(false, ApplicationDomain.currentDomain));
                        objectLoaderLocal.addEventListener(Event.COMPLETE , LocalComplit);                               
 
                        function LocalComplit(e:Event):void
                        {
                                objectLoaderLocal.removeEventListener(Event.COMPLETE , LocalComplit);
                                //var bytesW:ByteArray = new ByteArray();
                                //bytesW.writeBytes(objectLoaderLocal.);
                                //this.eventFunctionComplit(bytesW.readUTFBytes(bytesW.length));
 
                                //this.eventFunctionComplit(e.target.data);
                                this.Destroy();
                        }
 
                }
 
                // Инициализация прошла успешно
                private function EventFunctionInit(e:Event):void
                {
                        if(this.eventFunctionComplit is Function)
                        {
                                try
                                {
                                        //this.eventFunctionComplit(e.target.content as ByteArray);
                                        //var objectLoaderLocal:Loader = new Loader();
                                        //objectLoaderLocal.loadBytes(this.objectLoader.bytes, new LoaderContext(false, ApplicationDomain.currentDomain));
                                        //this.eventFunctionComplit(e.target.content as ByteArray);
                                        this.objectLoader.contentLoaderInfo.addEventListener(Event.COMPLETE , this.EventFunctionComplete);                               
                                        //this.eventFunctionComplit(this.objectLoader);
                                }
                                catch (t:ArgumentError)
                                {
                                        this.FunctionError(t.message);
                                }
                                catch (t:SecurityError)
                                {
                                        this.FunctionError(t.message);
                                }
                                catch (t:IOError)
                                {
                                        this.FunctionError(t.message);
                                }
                                catch (t:Error)
                                {
                                        this.FunctionError(t.message);
                                }
                                finally
                                {
                                        trace(this.objectLoader.contentLoaderInfo.bytes);
                                }
 
 
                        }
                        else
                        {
                                var err:Error = new Error('function eventFunctionComplit not found');
                                this.FunctionError(err.message);
                        }
                }
 
                private function EventFunctionProgress(e:ProgressEvent):void
                {
                        if(this.eventFunctionProgress is Function)
                        {
                                const thisLoaded:Number = Math.round((e.bytesLoaded/e.bytesTotal) * 10)*10;
                                this.eventFunctionProgress(thisLoaded);                               
                        }
                }
 
                private function EventFunctionError(e:ErrorEvent):void
                {
                        this.FunctionError(e.text);
                }
 
                private function FunctionError(err:String):void
                {
                        if(this.eventFunctionError is Function) this.eventFunctionError(err);
                        this.Destroy();
                }
 
 
 
 
        } // Конец класса
} // Конец пакета

А передачу параметров в вышеуказанный класс можно реализовать вот таким интерфейсом:
Код AS3:

package lib_loader
{
 
        public interface ILibLoader
        {
 
                // Interface methods:
                // Установить параметры объекта
                function set SetParam(paramObject:Object):void;
        }
 
}


Vreden 23.02.2013 01:43

Не понимаю, как логика работы вообще доходит до EventFunctionComplete, если при возникновении SecurityErrorEvent.SECURITY_ERROR все заканчивается на EventFunctionError.

Объясните, пожалуйста, как этот хак работает. Работает?

yasha005 23.02.2013 01:51

Цитата:

Сообщение от Vreden (Сообщение 1121972)
Не понимаю, как логика работы вообще доходит до EventFunctionComplete, если при возникновении SecurityErrorEvent.SECURITY_ERROR все заканчивается на EventFunctionError.

Объясните, пожалуйста, как этот хак работает. Работает?

Всё очень просто: если вы в момент загрузки контента не обращаетесь к нему, т.е. когда оно находится на этапе инициализации, то никаких ошибок не выдаст. После того как контент загрузился в первый лоадер, он загружается во второй лоадер. Причём вторым лоадером из первого мы этот контент считываем как поток двоичных данных, а не как контент, к которому можно обратиться как к типу DisplayObject. А уже после того как мы загрузили двоичные данные во второй лоадер, именно к нему можем обращаться как к контенту типа DisplayObject

GBee 23.02.2013 02:04

Ха они так и не починили это. Вам дешевле будет эту ссылку ловить и не грузить. А подставлять картинку свою (ну или эту же, но свою)

yasha005 23.02.2013 02:10

Цитата:

Сообщение от GBee (Сообщение 1121977)
Ха они так и не починили это. Вам дешевле будет эту ссылку ловить и не грузить. А подставлять картинку свою (ну или эту же, но свою)

Согласен, гораздо проще написать серверный скрипт, который будет забирать картинку с другого сервера, а сий запрос будет инициировать флэшка. Тогда и не понадобятся никакие обходные пути изолированной среды


Часовой пояс GMT +4, время: 12:05.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.