Форум 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)
Ха они так и не починили это. Вам дешевле будет эту ссылку ловить и не грузить. А подставлять картинку свою (ну или эту же, но свою)

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

Vreden 23.02.2013 03:01

На самом деле я надеялся на то, что есть способ предотвратить нарушение изолированной среды, в конце концов объект на том конце url является частью api vkontakte и должен быть способ его использования. Для меня весьма странен тот факт, что api возвращает url, который нельзя по сути использовать.

Но раз все так плохо, будем подставлять свою картину. Всем спасибо за ответы.

caseyryan 23.02.2013 17:03

Цитата:

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

Ну, речь-то не об этом шла ;)
К чему такие пляски с бубном? Ради одной маленькой картинки? Тут самый простой и разумный вариант - все-таки обрабатывать ошибку, а не пытаться от нее избавиться


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

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