Flash-MX
Ozon.ru
online:
Опрос
LOE2006-09-08
Какой браузер является для вас предпочтительным?
ответить и результаты
Новости сайта
Fisher2009-09-15
Работает портал ведического знания, с возможностью скачать лекции по ведам
Nox Noctis2006-10-29
Перевод на русский язык документации к Flash MX 2004 теперь расположен на нашем сервере. Версия для скачивания доступна здесь (2.1 mb). Значительная часть документации к Flash MX 2004 совпадает с документацией к Flash 8, поэтому почти все переведенные статьи по сей день актуальны.
LOE2006-09-08
Новый вопрос в голосовании. Присединяйтесь!
LOE2006-08-21
Выложены электронные версии литературы и документации
LOE2006-05-25
На сервере запущен сервис jabber! Приятного использования. подробности
programming by LOE
© Flash-mx.ru 2005-2007
Топ сайт/topsites/FMX-1.jpg
ElasticMind
Дата помещения: 2008-03-25
Автор: Tha Ltd.
оценка: ( 0.00/0)
обсудить
Топ авторы
silin: 11(ср.оц.: 7.22/23)
Nirth: 7
MureJIb: 4(ср.оц.: 6.00/7)
Clark Dols: 3(ср.оц.: 7.50/2)
Штрек: 3(ср.оц.: 6.67/6)
Igor: 2(ср.оц.: 4.33/3)
pogga: 2(ср.оц.: 10.00/2)
Flash-Maker: 1
ALFer: 1(ср.оц.: 10.00/2)
Ventur: 1(ср.оц.: 1.00/1)
Добавь свой исходник!

Valid HTML 4.01!
Valid CSS!
оНХЯЙНБНЕ ОПНДБХФЕМХЕ, ОНДДЕПФЙЮ ЯЮИРЮ, ПЮЯЙПСРХРЭ ЯЮИР


с 19.04.2006


Get legal. Get OpenOffice.org

автор: Ruzanov Igor

постановка задачи

Сделать в приложении под Flash Player 6 и 7 возможность загрузки файлов на сервер. Плюс нужно во флэше обработать событие загрузки файла и в случае успеха получить имя файла, который выбрал пользователь. И сделать это так, что бы этот способ поддерживался как можно большем количеством браузеров.

описание проблемы

Основная трудность - вызвать стандартный файловый диалог браузера. Обычными способами flash+js этого сделать нельзя (вернее мне не удалось найти :) и нужно как-то выкручиваться.

методы решения

a) Первый вариант решения - это размещение во фрейме с нулевой шириной формы с одним элементом input типа file:

<form name="fileform" action="up.php" method="post" enctype="multipart/form-data" id="fileform">
    <input type="file" name="filename" onChange="sendFile()">
</form>

Минимизировать По высоте текста
   1
   2
   3
   4
 // код JavaScript функции sendFile
 function sendFile() {
    fileform.submit();
 }


А из флэша вызывать JavaScript функцию (подробно методы вызова JavaScript функций из флэш описаны тут), которая будет программно вызывать метод click() файлового input'a в нашей форме и после выбора файла пользователем форма отправляет данные на сервер. Но, к сожалению, этот фокус пройдёт только в Internet Explorer поседних версий. Другие браузеры программный вызов метода click() не поддерживают.

Исходник варианта а) можно скачать здесь

б) Второй вариант решения - это открытие JavaScript'ом нового окна с обычной html формой, в которой пользователь выбирает файл и загружает его на сервер.

Минимизировать По высоте текста
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
 // JavaScript:
 function openWin(url) {
     var myWin; 
     if (!myWin || myWin.closed) { 
         myWin = window.open(url,
                 "blank",
                 "width=400,height=200,"+
                 "toolbar=0,location=0,"+
                 "directories=0,status=0,"+
                 "menubar=0,scrollbars=0,"+
                 "resizable=0,"+
                 "top="+((screen.height/2)-100)+","+
                 "left="+((screen.width/2)-200));
     } else {
         myWin.focus();
     } 
 }

Данная функция вызывается из флэша (например, через getURL) и если новое окно уже открыто, то наводим на него фокус или, в противном случае, создаём его. Для красоты располагаем его по центру экрана, вычисляя координаты top и left.

В открываемом новом окне будет находиться простая форма:

<form enctype="multipart/form-data" method="post" name="form" action="uphtml.php">
  <input type="file" name="filename" id="filename">
  <input type="submit" value="Upload">
</form>

В качестве серверной стороны будем использовать php скрипт. Это скрипт должен в случае успешной загрузки файла сохранить его в нужном месте и вернуть флэшу имя файла, а если загрузка прошла не удачно, то вернуть 0. Самый простой способ - это из нового окна вызвать метод SetVariable для флэш объекта (в новом окне можно получить доступ к окну, которое его открыло, через ссылку window.opener).

PHP скрипт генерирует html страницу, в которой JavaScript функция передаёт флешу результат загрузки:

Минимизировать По высоте текста
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
 if($_FILES["filenam"]["error"] != UPLOAD_ERR_OK)   {
     $res = 0;
 } else {                    
     $file = $_FILES["filename"]["name"];
     @rename($_FILES["filename"]["tmp_name"],$file);    
     $res = $file;
 }
 $page  = "<script language='JavaScript'>";
 $page .= "function send2Flash() {";
 $page .= "window.opener.document.index.SetVariable('res','".$res."');"
 $page .= "}";
 $page .= "</script></head>";
 $page .= "<body onLoad='send2Flash();window.close();'";
 $page .= "></body></html>"; 
 print($page);

где index - имя(id) флэш объекта.

Во флэше можно отреагировать на установку нового значения переменной res JavaScript'ом и вызвать функцию:

Минимизировать По высоте текста
   1
   2
   3
   4
   5
   6
 var res = null;
 _root.watch("res",jsReturn);
 function jsReturn() {
     // обработчик события - изменение res 
     // новое значение res находиться в arguments[2]
 }
Но, к сожалению, метод SetVariable нигде, кроме как в Mozilla(pc), Internet Explorer 5/6(pc), Firefox(pc) не работает. Тогда придется слегка изменить этот вариант и вместо SetVariable передавать данных флэшу при помощи прокси-флэшки и LocalConnection. (подробнее о таком виде коммуникации JS - Flash рассказано здесь.)

в) Окончательный вариант.
Всё остаётся без изменений, как и во втором варианте до момента передачи данных флэшу. Только для удобства форма и обработчик формы будут находиться в одном php файле. Плюс, поскольку url-адрес нового окна формируется на флэшовой стороне, то мы можем передать этому скрипту методом get какие-то данные из флэшки:

Минимизировать По высоте текста
   1
   2
   3
   4
 function openWin(url) {
     getURL("javascript:openWin('"+url+"');");
 };
 openWin("upwin.php?data=test");

Изменится только метод передачи данных флэшу.

Принцип метода: мы создаем на странице <div>, содержащий прокси-флэшку. Задача этой флэшки – принять те переменные, которые переданы ей через FlashVars и передать их при помощи LocalConnection в главную флэшку. Когда нам необходимо передать новые переменные, мы переписываем код тегов <object> и <embed> прокси-флэшки при помощи JavaScript, чем вызываем её перезагрузку. Таким образом, мы используем для передачи флэшовый механизм LocalConnection, а со стороны javascript используем только передачу переменных через FlashVars (что поддерживается всеми современными броузерами).

Теперь код функции send2Flash, генерируемый php на новой странице, будет иметь вид:

Минимизировать По высоте текста
   1
   2
   3
 $page .= "function send2Flash() {";
 $page .= window.opener.setFlashVariable(\"res\",\"".$res."\");
 $page .= "}";

Функция setFlashVariable находится на главной странице и переписывает код прокси-флэшки, передавая ей через FlashVars переменную:
Минимизировать По высоте текста
   1
   2
   3
   4
 function setFlashVariable (name, value) {
     var refresh = document.getElementById("refresh");
     refresh.innerHTML = refresh_html.split("$$$$").join(name+"="+value);
 }

Код для прокси-флэшки, которая будет регулярно перезагружаться и передавать сигналы главной флэшке:
Минимизировать По высоте текста
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
 var refresh_html =
     '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '+
     'codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/'+
     'flash/swflash.cab#version=7,0,0,0" '+ 
     'width="1" height="1" >'+
     '<param name="movie" value="refresh.swf" />'+
     '<param name="FlashVars" value="lcid='+connection_id+'&$$$$" />'+
     '<embed src="refresh.swf" '+
        'FlashVars="lcid='+connection_id+'&$$$$" '+
        'width="1" height="1" '+
        'type="application/x-shockwave-flash" '+
        'pluginspage="http://www.macromedia.com/go/getflashplayer" />'+
     '</object>';

Внутри прокси-флэшки не должно быть ничего, кроме следующего кода:
Минимизировать По высоте текста
   1
   2
   3
 var lc_name = "lc_"+lcid;
 var js_lc = new LocalConnection();
 js_lc.send(lc_name, "uploadCallBack", res);

В главной флэшке:
Минимизировать По высоте текста
   1
   2
   3
   4
   5
   6
 var lc_name = "lc_"+lcid;
 var js_lc = new LocalConnection();
 js_lc.connect(lc_name);    
 js_lc.uploadCallBack = function (res) {
     // обработчик
 }

Исходник окончательного варианта можно скачать тут.

вывод

Последний вариант должен работать в большинстве браузерах, даже в таких "проблематичных" как Opera и браузеры под Mac.
Тестировалось на IE 6, Firefox 1.5 и Opera 7.53