2006-07-29

FileReference 上傳圖檔

上傳圖檔後, 再載入該圖檔

為了避免中文檔名的影響,
上傳檔案的同時, 傳給後端一個 md5 編碼後的字串
並以該字串為上傳後的檔名

Frame Actions
import com.gsolo.encryption.MD5;

var uploadURL:String = "upload_uni_9.php";
var req:URLRequest = new URLRequest(uploadURL);
var myMD5:String;
var file:FileReference = new FileReference();

req.method = URLRequestMethod.POST;

// 按 upload_btn 選擇上傳的檔案upload_btn.addEventListener(MouseEvent.MOUSE_UP, myMouseUp);
function myMouseUp(e:Event):void{
file.browse([new FileFilter("Images", "*.jpg;*.gif;*.png")]);
}
//
file.addEventListener(Event.SELECT, myFileSelect);
file.addEventListener(Event.COMPLETE, myFileComplete);
// 選擇所欲上傳的圖檔後
function myFileSelect(e:Event):void{
var vars:URLVariables = new URLVariables();
myMD5 = MD5.encrypt(file.name+new Date().getTime());
vars.md5 = myMD5;
req.data = vars;
file.upload(req);
}
// 上傳完成後
function myFileComplete(e:Event):void{
var dotIndex:int = file.name.lastIndexOf(".");
var ext:String = file.name.substring(dotIndex);
var picURL:String = "./imgs/"+myMD5+ext;
// 載入圖片
var picReq:URLRequest = new URLRequest(picURL);
var pic:Loader = new Loader();
pic.load(picReq);
pic.x = 100;
pic.y = 100;
this.addChild(pic);
}

PHP
// 圖檔上傳後所欲存放的目錄
$up_dir = "./imgs/";
// 若目錄不存在, 則建立之
if(!is_dir($up_dir))
mkdir($up_dir, 0755);
// 取得上傳檔案的副檔名
$pos = strrpos($_FILES["Filedata"]["name"], ".");
if ($pos === false) {
$ext = "";
}else{
$ext = substr($_FILES["Filedata"]["name"], $pos);
}
// 以傳入的md5為儲存的檔名
$up_file = $up_dir . $_POST["md5"] . $ext;
// 將檔案放到設定的目錄內
move_uploaded_file($_FILES["Filedata"]["tmp_name"], $up_file);
chmod($up_file, 0777);

14 則留言:

KINK@BLOGGER 提到...

新德大...您好
我是kink,我用此範例還是會有"事件"沒反應的情況,要如何避免檔案比較大時,上傳會發生這種現象的狀況呢?

對於Complete事件,他是如何監聽的呢?
希望能針對這點改善情況....

麻煩新德大再指導一下小弟,謝謝

Shinder 提到...

檔案變大應該不會發生沒反應的情況, 有可能你的 addEventListener 沒執行到, 或者 addEventListener 時 listener function 還沒定義, 或者 listener function 後來被蓋掉...
再檢查看看, Good luck

KINK@BLOGGER 提到...

對了...新德大
我有加上ProgressEvent.PROGRESS的監聽!
所以才會覺得是flah端沒反應@@?

Unknown 提到...

林大哥您好:

我昨天買了您的新書「Flash CS3 ActionScirpt3.0 應用程式設計」,

有看到上傳圖片、上傳多張圖片那個章節,
正在努力學習中,

有一點想請教林大哥,
如果我在上傳圖檔時,
同時要利用post的方法,
上傳一些像標題、地址、電話等其他資料的話,
可能要怎麼寫呢?
謝謝......

Shinder 提到...

一般的 post 方式即可
如 p.493 的方式, 將 method 改成 POST 即可, 大概像這樣子:
var req:URLRequest = new URLRequest("upload_test2.php");
req.method = URLRequestMethod.POST;
var vars:URLVariables = new URLVariables();
vars.para = "測試";
req.data = vars;
var file:FileReference = new FileReference();
...
file.upload(req);

Unknown 提到...

謝謝大哥之前回應。

再請教林大哥一個問題。

小弟實作「多檔上傳」(p.507頁),發現二點:

1、flash沒有依照 files[]的陣列內容順序從頭到尾上傳,而有點隨機亂跳(p.509頁的圖片也有反應類似的結果)。

2、它竟然一次可同時上傳二個檔案。

感到有點困惑.....

請教大哥有無解決之道,謝謝。

Unknown 提到...

林大哥您好:

上次提到flash檔案上傳時沒有依照使用者所選取的檔案順序來上傳,會影響到上傳後寫到資料庫的順序,尤其是相片檔有故事情節,有先後順的性質,那還要寫一個「相片排序」功能,有點難處理。

後來小弟想到一個方法:

一、在偵聽Event.SELECT時,取得的陣列總數,
再寫個迴圈,再造一個my_data[]同樣數量的序號陣列:Date.getTime()+i


二、然後在執行upload()上傳的同時,這個陣列的序號值,跟著上傳的相片檔案上傳到後台。


三、寫進資料庫時,再利用mypost的序號來做為相片排序的依據即可。

謝謝。

(原本有附程式碼,但不被接受......)

Shinder 提到...

峰銘, 您好

感謝您提供您的作法, 可以給和您有相同需求的人一些參考 :)

milk 提到...

你好~想要請教你關於filereference裡upload跟load的問題
我在fileSelece裡面寫了fileReferenceload.load();
fileReferenceload.addEventListener(Event.COMPLETE,completeHandler);
然後completeHandler裡面寫了event.currentTarget.upload(uploadurl,"Filedata");去上傳檔案

但是這樣就會跑completeHandler兩次
想要請問怎樣才能把它們分開呢??
謝謝^^

milk 提到...

你好:想請問關於filereference的問題
我在我的fileSelectedHandler裡面先fileReferenceload.load();然後監聽完成後,在upload()檔案,但是這樣就會讓我的arraycollectiont出現兩樣東西,想要請問要怎麼才能把它們分開呢?
謝謝^^

ydmq 提到...

您好!
請教一下,
fileReferenceload.load();的作用是將圖檔load到本機的記憶內,
其資料型態為byteArray,雖可利用Loader及
addChild將記憶中的data顯示在螢幕上,
但想利用滑鼠去拖曳該圖片卻動不了,
不知有沒有方法可以將記憶體中的資料放在一個movieClip中?或sprite中?
謝謝!

Shinder 提到...

Loader的父類別為 DisplayObjectContainer, 所以你要做的事情, 應該用 Loader 就可以完成。再不然就把 Loader 物件放到 MC 物件裡。

Unknown 提到...

林大哥您好:

我是JyunYu,冒昧留言詢問因為小弟AS撰寫在FileReference使用遇到些問題,您這篇文章最後時間是2010了,不知道是否還在經營?如果可以請您協助一下~非常感恩

問題大概是這樣的

今天如果我要從swf下載檔案在 FileReference 可以直接寫成

file = new FileReference();
file.save(player.data, "rec.mp3");
//player.data 是存mp3的檔案

但是我今天的動作要求要將 player.data 的資料上傳到伺服器上。
起先我以為只要下URLRequestMethod.POST 相關參數就可以了,如下所示。

var url:String = "test.asp";
var goasp:URLRequest = new URLRequest(url);
var Variables:URLVariables = new URLVariables()
Variables.filename = (“player.data, abc.mp3”);
goasp.data = Variables;
goasp.method = URLRequestMethod.POST;
navigateToURL(goasp);

起先我以為沒什麼問題,我在asp用<%= Request.Form("filename") %>
有抓到abc.mp3的值,但我發現我的寫法完全錯誤

上述寫法 player.data 並沒有真正上傳到asp,只抓到 Variables.filename屬性值,當然我的寫法可能也有問題,經大費周章查原因,才發現navigateToURL只限二進制才可以進行。然而我的player.data裡面的mp3是影音編碼,用二進制的POST方式是辦不到的。不知道我的觀念正不正確?之後我發現大部分撰寫人員,會用FileReference.upload()與 FileReference browse()來進行,於是我寫了下面的程式,但是的程式已經有player.data所以不用使用到browse()選擇檔案,但是我要怎麼寫player.data 才會指向file變數裡? 如何使用Upload的時機才可以送出,player.data資料,屬性變數名稱是filename至test.asp。

var file:FileReference = new FileReference ();
file.source= (player.data,”abc.mp3”); //錯誤的地方
var goasp:URLRequest = new URLRequest(“test.asp”);
var Variables:URLVariables = new URLVariables()
Variables.filename = (player.data); //這應該是錯誤的
goasp.data = Variables;
goasp.method = URLRequestMethod.POST;
file.upload(goasp);


希望林大哥看得懂小弟的意思~如有空請協助幫忙,謝謝。

Shinder 提到...

可以參考這個
http://qops.blogspot.com/2010/08/flash-multipartform-data.html
但我沒有在寫 ASP, 所以沒辦法給你意見。

FB 留言