Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   API приложений и сред (http://www.flasher.ru/forum/forumdisplay.php?f=61)
-   -   загрузка аватарки пользователя vkontakte (http://www.flasher.ru/forum/showthread.php?t=197451)

HorusWM 07.04.2013 18:08

загрузка аватарки пользователя vkontakte
 
Пробовал загрузить во флешку аватар пользователя через Loader и URL loader, но в обоих случаях ошибки безопасности.
Вот эти шаги проделал:
Код AS3:

Security.allowDomain("*");
Security.loadPolicyFile("http://api.vk.com/crossdomain.xml");
 
var context:LoaderContext = new LoaderContext();
context.checkPolicyFile = true;
context.applicationDomain = ApplicationDomain.currentDomain;

В случае с Loader'ом:
Код AS3:

imageLoader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, ImageLoaded);
 
try
{
        imageLoader.load(new URLRequest(url), context);
}
catch (err:Error)
{
        ui.Print(err.message);
        handler(null);
}
 
private function ImageLoaded(e:Event):void
{
                        var bmp:BitmapData = new BitmapData(imageLoader.width, imageLoader.height, true, 0x00FFFFFF);
                        try
                        {
                                bmp.draw(e.target.content);
                        }
                        catch(err:Error)
                        {
                                // и тут я получаю SecurityError: Error #2122: Security sandbox violation: BitmapData.draw
                        }
}

В случае с URLLoader'ом:
Код AS3:

urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, UrlLoaderComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, UrlLoaderIOError);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, UrlLoaderSecurityError);
 
срабатывает UrlLoaderSecurityError()

Подскажите, как правильно загрузить аватар пользователя с его страницы в мое iFrame-приложение?

caseyryan 07.04.2013 18:56

Вот этот код надо выкинуть
Код AS3:

Security.allowDomain("*");
Security.loadPolicyFile("http://api.vk.com/crossdomain.xml");

Приложение не находится на домене api.vk.com

HorusWM 07.04.2013 19:29

Только это ничего не меняет, разве что теперь error#2122 сменился на error#2123.

Попробовал вариант описанный тут http://www.flasher.ru/forum/blog.php?b=208 (через Loader.loadBytes(LoaderInfo.bytes)), но LoaderInfo.bytes = null, хотя LoaderInfo.bytesLoaded показывает некое число загруженных байт. Что не так то?

caseyryan 07.04.2013 20:28

А что это за приложение? Чистый swf залитый в контакт или через iframe грузится?

HorusWM 07.04.2013 20:35

Цитата:

Сообщение от caseyryan (Сообщение 1128681)
А что это за приложение? Чистый swf залитый в контакт или через iframe грузится?

iFrame, я дописал в первом посте. Где-то читал, что некоторые заливают на сервер ВК флешку, которая подгружает фото, а затем тянут из нее, но неужели больше никак? Может через js загружать надо?

Сделал через обмен данными с сервером: ссылка на фото отправляется ему, он возвращает массив байт, описывающих изображение. Тему можно закрывать.

carrotoff 09.04.2013 17:27

Присоединяйся

HorusWM 13.04.2013 10:47

Цитата:

Сообщение от carrotoff (Сообщение 1128972)

Подписался)

caseyryan 13.04.2013 13:52

Цитата:

Сообщение от HorusWM (Сообщение 1128682)
Сделал через обмен данными с сервером: ссылка на фото отправляется ему, он возвращает массив байт, описывающих изображение. Тему можно закрывать.

А можно глянуть серверный код который это делает?
Чтобы свой велосипед не изобретать, когда это понадобится

Добавлено через 1 час 34 минуты
Таки сделал велосипед ) Может кому пригодится

Используется 2 класса на клиенте, и небольшой скрипт на сервере
Основной, универсальный пакет для запросов к серверу:
Код AS3:

package client {
 
        import flash.events.Event;
        import flash.events.IOErrorEvent;
        import flash.events.SecurityErrorEvent;
        import flash.net.URLLoader;
        import flash.net.URLLoaderDataFormat;
        import flash.net.URLRequest;
        import flash.net.URLRequestMethod;
        import flash.net.URLVariables;
        import flash.utils.ByteArray;
 
        public class Packet {
 
                public static const HOST:        String                = "http://hostname.com/";
                public static const SCRIPT:        String                = "call.php";
                public static var USER_ID:        String                = "userId";
                public static var PASSWORD:        String                = "pass";
 
 
                private var _callback:                Function        = null;
                private var _isBinary:                Boolean                = false;
 
                /**
                *
                * @param        method имя метода для передачи в параметр method на сервер
                * @param        callback вызывается когда в ответ на запрос приходят данные
                * в случае ошибки игнорируется
                */

                public function Packet(method:String, callback:Function, params:Object = null, isBinary:Boolean = false) {
                        _callback                                = callback;
                        _isBinary                                = isBinary;
                        var loader:        URLLoader        = new URLLoader();
                        loader.addEventListener(Event.COMPLETE, onComplete);
                        loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
                        if (!_isBinary) {
                                loader.dataFormat        = URLLoaderDataFormat.VARIABLES;
                        } else {
                                loader.dataFormat        = URLLoaderDataFormat.BINARY;
                        }
                        var vars:URLVariables        = new URLVariables();
                        vars['method']                        = method;
                        vars['pass']                        = PASSWORD;
                        vars['userId']                        = USER_ID;
                        if (params != null) {
                                for (var i:String in params) {
                                        vars[i] = params[i];
                                }
                        }
                        var rand:        String                = "?" + int(Math.random() * 100000);
                        var request:URLRequest        = new URLRequest(Packet.HOST + Packet.SCRIPT + rand);
                        request.method                        = URLRequestMethod.POST;
                        request.data                        = vars;
                        trace(request.data.toString());
                        try {
                                loader.load(request);
                        } catch (e:Error) {
                                trace(e.getStackTrace());
                        }
 
                }
 
                private function onSecurityError(e:SecurityErrorEvent):void {
                        e.target.removeEventListener(Event.COMPLETE, onComplete);
                        e.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        e.target.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
                }
 
                private function onIOError(e:IOErrorEvent):void {
                        e.target.removeEventListener(Event.COMPLETE, onComplete);
                        e.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        e.target.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
                }
 
                private function onComplete(e:Event):void {
                        e.target.removeEventListener(Event.COMPLETE, onComplete);
                        e.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        e.target.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
                        if (!_isBinary) {
                                var data:Object = e.target.data as Object;
                                if (_callback != null) {
                                        _callback.call(null, data);
                                }
                        } else {
                                var byteArray:ByteArray        = e.target.data as ByteArray;
                                if (_callback != null) {
                                        _callback.call(null, byteArray);
                                }
                        }
                }
        }
}

Вспомогательный пакет для загрузки изображения:

Код AS3:

package client {
        import flash.display.Bitmap;
        import flash.display.Loader;
        import flash.events.Event;
        import flash.events.IOErrorEvent;
        import flash.utils.ByteArray;
        import flash.system.LoaderContext;
        /**
        * загружает картинку с любого домена,
        * через отправку запроса своему серверу
        * и получение этой картинки уже от него
        */

        public class ProxiedImage {
 
                private var _callback:        Function        = null;
 
                /**
                * @param        imageUrl прямая ссылка на картинку
                * @param        callback метод с единственным параметром image:Bitmap
                */

                public function ProxiedImage(imageUrl:String, callback:Function) {
                        _callback        = callback;
                        if (_callback == null) {
                                throw new ArgumentError("callback cannot be null!");
                        }
                        var packet:Packet = new Packet("getImage", onLoad, { url: imageUrl }, true);
                }
                private function onLoad(params:Object):void {
                        if (_callback == null) return;
                        var imageBytes:        ByteArray        = params as ByteArray;
                        var loader:                Loader                = new Loader();
                        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
                        try {
                                var context:LoaderContext = new LoaderContext(true);
                                loader.loadBytes(imageBytes, context);
                        } catch (e:Error) {
                                loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
                                loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
                        }
 
                }
 
                private function onComplete(e:Event):void {
                        e.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        e.target.removeEventListener(Event.COMPLETE, onComplete);
                        var image:Bitmap = e.target.content as Bitmap;
                        _callback.call(null, image);
                }
 
                private function onIOError(e:IOErrorEvent):void {
                        e.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
                        e.target.removeEventListener(Event.COMPLETE, onComplete);
                }
        }
}

Ну и php скрипт, который грузит картинку и возвращает байты
PHP код:

$method = $_POST['method'];
if (
$method == "getImage") {
    
$url    = $_POST['url'];
           
$url_reg = "/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/";
    if (
preg_match($url_reg, $url)) {
        
$file    = file_get_contents($url);
        echo 
$file;
    }
    
} 

Используется все просто.
там, где надо загрузить картинку с другого домена, создаем метод, в который будет возвращаться картинка:

Код AS3:

 
private function onImageLoaded(image:Bitmap):void {
      addChild(image); // вуаля, картинка добавлена
}

и отправляем запрос на загрузку картинки серверу
Код AS3:

var pi:ProxiedImage = new ProxiedImage("http://example.com/image.jpg", onImageLoaded);

Все, после загрузки картинка передастся как аргумент созданному методу

HorusWM 13.04.2013 17:44

У нас немножко по-другому:
Есть отдельный сайт со страницей-генератором на нем, типа http://НекийСайт.com/Default.aspx?img=, который мы передаем как путь +url аватарки для загрузки как параметр. Т.е., выглядит примерно так:
Код AS3:

url = "http://НекийСайт.com/Default.aspx?img=" +"http://cs416319.vk.me/бла-бла-бла.jpg";
imageLoader.load(new URLRequest(url), context);

Страница формирует изображение по переданному параметру и отдает его в наш загрузчик, все) К этой странице может обращаться большое кол-во пользователей без опасности нагрузки на сервер приложения. Загружать можно любые изображения, нужны только прямые ссылки на них.
Скрипт страницы (там 5-10 строк, в общем-то) и длл сейчас выковырять не могу, серверный программист не на месте.

Кстати, caseyryan, у вас ошибка безопасности не вылезает там без LoaderContext?

caseyryan 13.04.2013 18:55

Цитата:

Кстати, caseyryan, у вас ошибка безопасности не вылезает там без LoaderContext?
Да, верно, про него забыл ). Но в принципе, добавить не проблема.
Цитата:

К этой странице может обращаться большое кол-во пользователей без опасности нагрузки на сервер приложения.
А картинка грузится на сам сервер?


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

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