使用 FileReference 類別

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

FileReference 物件表示用戶端或伺服器電腦中的資料檔案。FileReference 類別的方法可以讓您的應用程式在本機載入和儲存資料檔案,以及與遠端伺服器之間來回傳輸檔案資料。

FileReference 類別現在提供兩種不同的方式供您載入、傳輸及儲存資料檔案。導入 FileReference 類別後,本類別就包括 browse() 方法、 upload() 方法以及 download() 方法。使用 browse() 方法,允許使用者選取檔案。使用 upload() 方法,將檔案資料傳輸至遠端伺服器。使用 download() 方法,從伺服器擷取該資料後儲存至本機檔案。從 Flash Player 10 和 Adobe AIR 1.5 開始,FileReference 類別還包括 load() save() 方法。 load() save() 方法也可以讓您直接存取以及儲存本機檔案。使用這些方法類似於在 URLLoader 和 Loader 類別中以對應方式命名的方法。

備註: 延伸出 FileReference 類別的 File 類別,以及 FileStream 類別,提供了使用檔案和本機檔案系統的其他函數。僅 AIR 支援 File 和 FileStream 類別,Flash Player 並不支援。

Adobe 推薦的資源

載入和儲存本機檔案

Kevin Hoyt
在此影片中,Kevin Hoyt 呈現使用 Flash 載入和儲存本機內容有多簡單。

FileReference 類別

每個 FileReference 物件都代表本機電腦中的一個資料檔案。FileReference 類別的屬性包含以下相關資訊:檔案的大小、類型、檔名、副檔名、建立者、建立日期和修改日期。

備註: 只有 Mac OS 支援 creator 屬性,所有其它的平台則會傳回 null
備註: 只有 Adobe AIR 才支援 extension 屬性。

您可以用下列兩種方法建立 FileReference 類別的實體:

  • 使用 new 運算子,如下列程式碼所示:
    import flash.net.FileReference; 
    var fileRef:FileReference = new FileReference();
  • 呼叫 FileReferenceList.browse() 方法,這個方法會開啟對話方塊,提示使用者選取一個或多個要上傳的檔案。接著,如果使用者成功選取一個或多個檔案,方法便會建立 FileReference 物件的陣列。

一旦建立 FileReference 物件之後,您就可以執行下列工作:

  • 呼叫 FileReference.browse() 方法,這個方法會開啟對話方塊,提示使用者從本機檔案系統選取一個檔案。這通常會在下列呼叫之前完成,即呼叫 FileReference.upload() 方法或 FileReference.load() 方法。呼叫 FileReference.upload() 方法,將檔案上傳至遠端伺服器。呼叫 FileReference.load() 方法,開啟本機檔案。

  • 呼叫 FileReference.download() 方法。 download() 方法會開啟對話方塊,讓使用者選取新檔案的儲存位置。接著,方法會從伺服器下載資料,並儲存在新檔案中。

  • 呼叫 FileReference.load() 方法。這個方法會使用 browse() 方法,開始從先前選取的檔案載入資料。必須先完成 browse() 作業 (使用者選取檔案),才能呼叫 load() 方法。

  • 呼叫 FileReference.save() 方法。這個方法會開啟對話方塊,提示使用者在本機檔案系統上選擇單一檔案位置。然後,再將資料儲存至指定的位置。

備註: 由於一次只能開啟一個對話方塊,因此一次只能執行一個 browse() download() save() 動作。

直到下列其中一種情況發生之前,不會定義 FileReference 物件屬性,例如 name size modificationDate

  • 已經呼叫 FileReference.browse() 方法或 FileReferenceList.browse() 方法,而且使用者已經從對話方塊中選取檔案。

  • 已經呼叫 FileReference.download() 方法,而且使用者已經從對話方塊中指定新的檔案位置。

備註: 執行下載動作時,在下載作業完成之前,只能填入 FileReference.name 屬性。檔案下載完成後,就可以使用所有的屬性。

在呼叫 FileReference.browse() FileReferenceList.browse() FileReference.download() FileReference.load() FileReference.save() 方法執行時,大部分播放程式會繼續進行 SWF 檔的播放,包括傳送事件和執行程式碼。

在上傳和下載作業中,SWF 檔只能存取其本身網域 (包含原則檔所指定的任何網域) 內的檔案。如果伺服器與啟動上傳或下載的 SWF 檔不在相同的網域中,您必須將原則檔存放在包含所要存取檔案的伺服器上。

請參閱 FileReference

從檔案載入資料

FileReference.load() 方法可讓您將資料從本機檔案載入記憶體。

備註: 若要載入記憶體,您的程式碼必須先呼叫 FileReference.browse() 方法,讓使用者選取要載入的檔案。此限制不適用於應用程式安全執行程序的 Adobe AIR 中執行的內容

FileReference.load() 方法會在被呼叫後立即傳回,但並不是立即就可使用正在上傳的資料。FileReference 物件會傳送事件,在載入程序的每個步驟都叫用偵聽程式方法。

在載入程序期間,FileReference 物件會傳送下列事件:

  • open 事件 ( Event.OPEN ):在載入作業開始時傳送。

  • progress 事件 ( ProgressEvent.PROGRESS ):在從檔案讀取資料時以資料位元組定期傳送。

  • complete 事件 ( Event.COMPLETE ):在載入作業順利完成時傳送。

  • ioError 事件 ( IOErrorEvent.IO_ERROR ):如果載入程序因為在開啟或讀取檔案資料時發生輸入/輸出錯誤而失敗時,就會傳送。

當 FileReference 物件傳送 complete 事件時,載入的資料可以做為 FileReference 物件的 data 屬性中之 ByteArray 存取。

下列範例會示範如何提示使用者選取檔案,然後將資料從檔案載入記憶體:

package 
{ 
     import flash.display.Sprite; 
    import flash.events.*;  
    import flash.net.FileFilter; 
    import flash.net.FileReference; 
    import flash.net.URLRequest; 
    import flash.utils.ByteArray; 
 
    public class FileReferenceExample1 extends Sprite 
    { 
        private var fileRef:FileReference; 
        public function FileReferenceExample1() 
        { 
            fileRef = new FileReference(); 
            fileRef.addEventListener(Event.SELECT, onFileSelected); 
            fileRef.addEventListener(Event.CANCEL, onCancel); 
            fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError); 
            fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
                        onSecurityError); 
            var textTypeFilter:FileFilter = new FileFilter("Text Files (*.txt, *.rtf)", 
                        "*.txt;*.rtf"); 
            fileRef.browse([textTypeFilter]); 
        } 
        public function onFileSelected(evt:Event):void 
        { 
            fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress); 
            fileRef.addEventListener(Event.COMPLETE, onComplete); 
            fileRef.load(); 
        } 
 
        public function onProgress(evt:ProgressEvent):void 
        { 
            trace("Loaded " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); 
        } 
 
        public function onComplete(evt:Event):void 
        { 
            trace("File was successfully loaded."); 
            trace(fileRef.data); 
        } 
 
        public function onCancel(evt:Event):void 
        { 
            trace("The browse request was canceled by the user."); 
        } 
 
        public function onIOError(evt:IOErrorEvent):void 
        { 
            trace("There was an IO Error."); 
        } 
        public function onSecurityError(evt:Event):void 
        { 
            trace("There was a security error."); 
        } 
    } 
}

範例程式碼會先建立名為 fileRef 的 FileReference 物件,然後再呼叫其 browse() 方法。 browse() 方法會開啟對話方塊,提示使用者選取檔案。選取檔案後,程式碼會叫用 onFileSelected() 方法。這個方法會為 progress complete 事件加入偵聽程式,然後呼叫 FileReference 物件的 load() 方法。範例中的其它處理常式方法只會輸出訊息,以報告載入作業的進度。載入完成時,應用程式便會使用 trace() 方法,顯示所載入檔案的內容。

在 Adobe AIR 中,FileStream 類別提供其他函數,以便從本機檔案讀取資料。請參閱 讀取和寫入檔案

將資料儲存至本機檔案

FileReference.save() 方法可讓您將資料儲存至本機檔案。首先,方法會開啟對話方塊,讓使用者輸入檔案名稱以及檔案的儲存位置。當使用者選取檔案名稱和儲存位置之後,資料隨即寫入新檔案。當檔案儲存成功時,本機檔案的屬性就會填入 FileReference 物件的屬性。

備註: 您的程式碼只能呼叫 FileReference.save() 方法來回應使用者事件 (例如,按下滑鼠或按下按鍵事件的使用者啟動的事件)。否則就會擲出錯誤。此限制不適用於應用程式安全執行程序的 Adobe AIR 中執行的內容。

FileReference.save() 方法在遭到呼叫之後會立即傳回。接著,FileReference 物件會傳送事件,在檔案儲存程序的每個步驟都呼叫偵聽程式方法。

在檔案儲存程序期間,FileReference 物件會傳送下列事件:

  • select 事件 ( Event.SELECT ):在使用者指定所要儲存新檔案的檔案名稱和位置時傳送。

  • cancel 事件 ( Event.CANCEL ):在使用者按一下對話方塊中的「取消」按鈕時傳送。

  • open 事件 ( Event.OPEN ):在儲存作業開始時傳送。

  • progress 事件 ( ProgressEvent.PROGRESS ):在資料位元組儲存至檔案時定期傳送。

  • complete 事件 ( Event.COMPLETE ):在儲存作業順利完成時傳送。

  • ioError 事件 ( IOErrorEvent.IO_ERROR ):如果儲存程序因為嘗試將資料儲存至檔案時發生輸入/輸出錯誤而失敗時,就會傳送。

傳入 FileReference.save() 方法之 data 參數中的物件類型將決定資料寫入檔案的方式:

  • 如果是 String 值,則會使用 UTF-8 編碼,將這個值儲存為文字檔案。

  • 如果是 XML 物件,則會以 XML 格式寫入至檔案,並保留所有格式設定。

  • 如果是 ByteArray 物件,則其內容會直接寫入至檔案而不經過轉換。

  • 如果是其它物件, FileReference.save() 方法會呼叫該物件的 toString() 方法,然後將產生的 String 值儲存為 UTF-8 文字檔案。如果無法呼叫物件的 toString() 方法,則會擲回錯誤。

如果 data 參數的值為 null ,則會擲回錯誤。

下列程式碼會擴充上述 FileReference.load() 方法的範例。從檔案讀取資料之後,這個範例會提示使用者輸入檔案名稱,然後將資料儲存在新檔案中:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.*;  
    import flash.net.FileFilter; 
    import flash.net.FileReference; 
    import flash.net.URLRequest; 
    import flash.utils.ByteArray; 
 
    public class FileReferenceExample2 extends Sprite 
    { 
        private var fileRef:FileReference; 
        public function FileReferenceExample2() 
        { 
            fileRef = new FileReference(); 
            fileRef.addEventListener(Event.SELECT, onFileSelected); 
            fileRef.addEventListener(Event.CANCEL, onCancel); 
            fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError); 
            fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, 
                        onSecurityError); 
            var textTypeFilter:FileFilter = new FileFilter("Text Files (*.txt, *.rtf)", 
                        "*.txt;*.rtf"); 
            fileRef.browse([textTypeFilter]); 
        } 
        public function onFileSelected(evt:Event):void 
        { 
            fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress); 
            fileRef.addEventListener(Event.COMPLETE, onComplete); 
            fileRef.load(); 
        } 
 
        public function onProgress(evt:ProgressEvent):void 
        { 
            trace("Loaded " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); 
        } 
        public function onCancel(evt:Event):void 
        { 
            trace("The browse request was canceled by the user."); 
        } 
        public function onComplete(evt:Event):void 
        { 
            trace("File was successfully loaded."); 
            fileRef.removeEventListener(Event.SELECT, onFileSelected); 
            fileRef.removeEventListener(ProgressEvent.PROGRESS, onProgress); 
            fileRef.removeEventListener(Event.COMPLETE, onComplete); 
            fileRef.removeEventListener(Event.CANCEL, onCancel); 
            saveFile(); 
        } 
        public function saveFile():void 
        { 
            fileRef.addEventListener(Event.SELECT, onSaveFileSelected); 
            fileRef.save(fileRef.data,"NewFileName.txt"); 
        } 
 
        public function onSaveFileSelected(evt:Event):void 
        { 
            fileRef.addEventListener(ProgressEvent.PROGRESS, onSaveProgress); 
            fileRef.addEventListener(Event.COMPLETE, onSaveComplete); 
            fileRef.addEventListener(Event.CANCEL, onSaveCancel); 
        } 
 
        public function onSaveProgress(evt:ProgressEvent):void 
        { 
            trace("Saved " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); 
        } 
         
        public function onSaveComplete(evt:Event):void 
        { 
            trace("File saved."); 
            fileRef.removeEventListener(Event.SELECT, onSaveFileSelected); 
            fileRef.removeEventListener(ProgressEvent.PROGRESS, onSaveProgress); 
            fileRef.removeEventListener(Event.COMPLETE, onSaveComplete); 
            fileRef.removeEventListener(Event.CANCEL, onSaveCancel); 
        } 
 
        public function onSaveCancel(evt:Event):void 
        { 
            trace("The save request was canceled by the user."); 
        } 
 
        public function onIOError(evt:IOErrorEvent):void 
        { 
            trace("There was an IO Error."); 
        } 
        public function onSecurityError(evt:Event):void 
        { 
            trace("There was a security error."); 
        } 
    } 
}

從檔案載入所有資料後,程式碼會呼叫 onComplete() 方法。 onComplete() 方法會移除載入事件的偵聽程式,然後呼叫 saveFile() 方法。 saveFile() 方法會呼叫 FileReference.save() 方法。 FileReference.save() 方法會開啟新的對話方塊,讓使用者輸入新的檔案名稱和儲存檔案的位置。其餘事件偵聽程式方法都會追蹤檔案儲存程序的進度,直到程序完成為止。

在 Adobe AIR 中,FileStream 類別提供其他函數,以便將資料寫入本機檔案中。請參閱 讀取和寫入檔案

將檔案上傳到伺服器

如果要將檔案上傳到伺服器,請先呼叫 browse() 方法,讓使用者可以選取一個或多個要上傳的檔案。然後,呼叫 FileReference.upload() 方法時,就會將選取的檔案傳輸到伺服器。如果使用者使用 FileReferenceList.browse() 方法選取多個檔案,Flash Player 就會建立包含所選取檔案的陣列,並命名為 FileReferenceList.fileList 。然後,您就可以使用 FileReference.upload() 方法分別上傳每一個檔案。

備註: FileReference.browse() 方法只能讓您上傳單一檔案。若要讓使用者可以上傳多個檔案,請使用 FileReferenceList.browse() 方法。

根據預設,系統檔案挑選器對話方塊可以讓使用者從本機電腦挑選任何類型的檔案。開發人員可以使用 FileFilter 類別,並將檔案篩選實體的陣列傳遞給 browse() 方法,以指定一或多個自訂檔案類型篩選:

var imageTypes:FileFilter = new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg; *.jpeg; *.gif; *.png"); 
var textTypes:FileFilter = new FileFilter("Text Files (*.txt, *.rtf)", "*.txt; *.rtf"); 
var allTypes:Array = new Array(imageTypes, textTypes); 
var fileRef:FileReference = new FileReference(); 
fileRef.browse(allTypes);

當使用者選取檔案,然後按一下系統檔案挑選器中的「開啟」按鈕後,就會送出 Event.SELECT 事件。如果已經使用 FileReference.browse() 方法選取要上傳的檔案,下列程式碼會將檔案傳送至網站伺服器:

var fileRef:FileReference = new FileReference(); 
fileRef.addEventListener(Event.SELECT, selectHandler); 
fileRef.addEventListener(Event.COMPLETE, completeHandler); 
try 
{ 
    var success:Boolean = fileRef.browse(); 
} 
catch (error:Error) 
{ 
    trace("Unable to browse for files."); 
} 
function selectHandler(event:Event):void 
{ 
    var request:URLRequest = new URLRequest("http://www.[yourdomain].com/fileUploadScript.cfm") 
    try 
    { 
        fileRef.upload(request); 
    } 
    catch (error:Error) 
    { 
        trace("Unable to upload file."); 
    } 
} 
function completeHandler(event:Event):void 
{ 
    trace("uploaded"); 
}
使用 FileReference.upload() 方法將資料傳送到伺服器時,您可以利用 URLRequest.method URLRequest.data 屬性,以便使用 POST GET 方法來傳送變數。

當您嘗試使用 FileReference.upload() 方法上傳檔案時,會傳送下列事件:

  • open 事件 ( Event.OPEN ):在上傳作業開始時傳送。

  • progress 事件 ( ProgressEvent.PROGRESS ):在上傳檔案的資料位元組時定期傳送。

  • complete 事件 ( Event.COMPLETE ):在上傳作業順利完成時傳送。

  • httpStatus 事件 ( HTTPStatusEvent.HTTP_STATUS ):在上傳程序因為 HTTP 錯誤而失敗時傳送。

  • httpResponseStatus 事件 ( HTTPStatusEvent.HTTP_RESPONSE_STATUS ):當 upload() uploadUnencoded() 方法呼叫嘗試透過 HTTP 存取資料,而且 Adobe AIR 能夠偵測並傳回要求的狀態碼時傳送。

  • securityError 事件 ( SecurityErrorEvent.SECURITY_ERROR ):在上傳作業因為安全性違規而失敗時傳送。

  • uploadCompleteData 事件 ( DataEvent.UPLOAD_COMPLETE_DATA ):在已經順利上傳並從伺服器接收資料以後傳送。

  • ioError 事件 ( IOErrorEvent.IO_ERROR ):在上傳程序因為下列任一原因而失敗時傳送:

    • Flash Player 讀取、寫入或傳送檔案時發生輸入/輸出錯誤。

    • SWF 嘗試將檔案上傳至需要驗證 (如使用者名稱和密碼) 的伺服器。上傳期間,Flash Player 沒有提供讓使用者輸入密碼的工具。

    • url 參數的值包含無效的通訊協定。 FileReference.upload() 方法必須使用 HTTP 或 HTTPS。

Flash Player 並不完全支援需要驗證的伺服器。只有在使用瀏覽器外掛程式或 Microsoft ActiveX® 控制項之瀏覽器中執行的 SWF 檔,才能提供對話方塊,以提示使用者輸入使用者名稱和密碼進行驗證,而且只能下載檔案。如果使用外掛程式或 ActiveX 控制項上傳檔案,或是使用獨立或外部播放程式進行上傳/下載作業,則檔案傳輸會失敗。

若要在 ColdFusion 中建立伺服器指令碼,以接受透過 Flash Player 上傳的檔案,您可以參考下列程式碼:

<cffile action="upload" filefield="Filedata" destination="#ExpandPath('./')#" nameconflict="OVERWRITE" />

這段 ColdFusion 程式碼會上傳由 Flash Player 送出的檔案,並將它儲存在 ColdFusion 範本所在的相同目錄中,而且會覆寫任何具有相同名稱的檔案。上一段程式碼使用的程式碼行數是接受檔案上傳所需的最少行數,因此這段指令碼不可以用於正式的執行環境。最理想的方式是加入資料驗證功能,以確保使用者只能上傳可接受的檔案類型 (如影像檔案),而不使用具有潛在危險的伺服器端指令碼。

下列程式碼將示範如何使用 PHP 進行檔案上傳作業,其中也包括資料驗證。這段指令碼會將上傳目錄中可上傳的檔案數量限制為 10,並確保檔案大小少於 200 KB,而且限制只能上傳 JPEG、GIF 或 PNG 檔案並儲存到檔案系統。

<?php 
$MAXIMUM_FILESIZE = 1024 * 200; // 200KB 
$MAXIMUM_FILE_COUNT = 10; // keep maximum 10 files on server 
echo exif_imagetype($_FILES['Filedata']); 
if ($_FILES['Filedata']['size'] <= $MAXIMUM_FILESIZE) 
{ 
    move_uploaded_file($_FILES['Filedata']['tmp_name'], "./temporary/".$_FILES['Filedata']['name']); 
    $type = exif_imagetype("./temporary/".$_FILES['Filedata']['name']); 
    if ($type == 1 || $type == 2 || $type == 3) 
    { 
        rename("./temporary/".$_FILES['Filedata']['name'], "./images/".$_FILES['Filedata']['name']); 
    } 
    else 
    { 
        unlink("./temporary/".$_FILES['Filedata']['name']); 
    } 
} 
$directory = opendir('./images/'); 
$files = array(); 
while ($file = readdir($directory)) 
{ 
    array_push($files, array('./images/'.$file, filectime('./images/'.$file))); 
} 
usort($files, sorter); 
if (count($files) > $MAXIMUM_FILE_COUNT) 
{ 
    $files_to_delete = array_splice($files, 0, count($files) - $MAXIMUM_FILE_COUNT); 
    for ($i = 0; $i < count($files_to_delete); $i++) 
    { 
        unlink($files_to_delete[$i][0]); 
    } 
} 
print_r($files); 
closedir($directory); 
 
function sorter($a, $b) 
{ 
    if ($a[1] == $b[1]) 
    { 
        return 0; 
    } 
    else 
    { 
        return ($a[1] < $b[1]) ? -1 : 1; 
    } 
} 
?>

您可以使用 POST GET 要求方法,將其它變數傳遞給上傳指令碼。若要將其它 POST 變數傳遞給上傳指令碼,請使用下列程式碼:

var fileRef:FileReference = new FileReference(); 
fileRef.addEventListener(Event.SELECT, selectHandler); 
fileRef.addEventListener(Event.COMPLETE, completeHandler); 
fileRef.browse(); 
function selectHandler(event:Event):void 
{ 
    var params:URLVariables = new URLVariables(); 
    params.date = new Date(); 
    params.ssid = "94103-1394-2345"; 
    var request:URLRequest = new URLRequest("http://www.yourdomain.com/FileReferenceUpload/fileupload.cfm"); 
    request.method = URLRequestMethod.POST; 
    request.data = params; 
    fileRef.upload(request, "Custom1"); 
} 
function completeHandler(event:Event):void 
{ 
    trace("uploaded"); 
}

上述範例會建立 URLVariables 物件,可傳遞給遠端伺服器端指令碼。在舊版 ActionScript 中,您可以將值傳入查詢字串,以便將變數傳遞給伺服器上傳指令碼。ActionScript 3.0 則允許您使用 URLRequest 物件將變數傳遞給遠端指令碼,可讓您在傳遞資料時使用 POST GET 方法,因而使得傳遞大型資料集的作業更容易、更簡潔。為了指定變數使用 GET POST 要求方法來傳遞,您可以分別將 URLRequest.method 屬性設為 URLRequestMethod.GET URLRequestMethod.POST

ActionScript 3.0 也可以讓您覆寫預設的 Filedata 上傳檔案欄位名稱,方式是:在使用 upload() 方法時加上第二個參數,如上一個範例中所示 (以 Custom1 取代預設值 Filedata )。

根據預設,Flash Player 並不會傳送測試性上傳作業,不過您可以傳遞 true 值做為 upload() 方法的第三個參數來覆寫這項預設值。測試上傳作業的目的是要檢查是否可以完成實際的檔案上傳作業,必要時,也可以一併檢查伺服器驗證作業是否成功。

備註: 目前,測試上傳作業僅適用於 Windows 平台上的 Flash Player。

處理檔案上傳的伺服器指令碼應該要有包含下列元素的 HTTP POST 要求:

  • 值為 multipart/form-data Content-Type

  • name 特質設為 " Filedata ",而且 filename 特質設為原始檔案名稱的 Content-Disposition 。您可以傳遞一個值給 FileReference.upload() 方法中的 uploadDataFieldName 參數,指定自訂的 name 特質。

  • 檔案的二進位內容。

以下是 HTTP POST 要求樣本:

POST /handler.asp HTTP/1.1 
Accept: text/* 
Content-Type: multipart/form-data; 
boundary=----------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
User-Agent: Shockwave Flash 
Host: www.mydomain.com 
Content-Length: 421 
Connection: Keep-Alive 
Cache-Control: no-cache 
 
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6  
Content-Disposition: form-data; name="Filename" 
 
sushi.jpg  
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
Content-Disposition: form-data; name="Filedata"; filename="sushi.jpg" 
Content-Type: application/octet-stream 
 
Test File  
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
Content-Disposition: form-data; name="Upload" 
 
Submit Query 
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
(actual file data,,,)

下列 HTTP POST 要求樣本會傳送 api_sig api_key auth_token 等三個 POST 變數,並使用 "photo" 這個自訂上傳資料欄位名稱值:

POST /handler.asp HTTP/1.1 
Accept: text/* 
Content-Type: multipart/form-data; 
boundary=----------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
User-Agent: Shockwave Flash 
Host: www.mydomain.com 
Content-Length: 421 
Connection: Keep-Alive 
Cache-Control: no-cache 
 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7 
Content-Disposition: form-data; name="Filename" 
 
sushi.jpg 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7 
Content-Disposition: form-data; name="api_sig" 
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7 
Content-Disposition: form-data; name="api_key" 
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7 
Content-Disposition: form-data; name="auth_token" 
 
XXXXXXXXXXXXXXXXXXXXXXX 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7 
Content-Disposition: form-data; name="photo"; filename="sushi.jpg" 
Content-Type: application/octet-stream 
 
(actual file data,,,) 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7 
Content-Disposition: form-data; name="Upload" 
 
Submit Query 
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7--

從伺服器下載檔案

您可以讓使用者利用 FileReference.download() 方法從伺服器下載檔案,這個方法需要用到 request defaultFileName 兩個參數。第一個參數為 URLRequest 物件,其中包含要下載之檔案的 URL。第二個參數是選擇性參數,它可以讓您指定顯示在「下載檔案」對話方塊中的預設檔案名稱。如果您省略第二個參數 defaultFileName ,就會採用指定的 URL 檔名。

下列程式碼將從 SWF 檔案所在的相同目錄中下載 index.xml 檔案:

var request:URLRequest = new URLRequest("index.xml"); 
var fileRef:FileReference = new FileReference(); 
fileRef.download(request);

如果不想使用 index.xml,而想以 currentnews.xml 做為預設名稱,請指定 defaultFileName 參數,如下列程式碼片段所示:

var request:URLRequest = new URLRequest("index.xml"); 
var fileToDownload:FileReference = new FileReference(); 
fileToDownload.download(request, "currentnews.xml");

當伺服器檔案名稱不具意義或是由伺服器自行產生時,重新命名檔案是不錯的做法。而且,在不直接下載檔案而使用伺服器端指令碼下載檔案的情況下,明確指定 defaultFileName 參數也是很好的處理方式。例如,當伺服器端指令碼是依據傳遞給它的 URL 變數下載特定的檔案時,您就必須指定 defaultFileName 參數。否則,已下載檔案的預設名稱將是您伺服器端指令碼的名稱。

您也可以將參數附加到 URL,藉由使用 download() 方法,將資料傳送給伺服器,以供伺服器指令碼進行剖析。下列 ActionScript 3.0 程式碼片段將會依據傳遞給 ColdFusion 指令碼的參數下載文件:

package 
{ 
    import flash.display.Sprite; 
    import flash.net.FileReference; 
    import flash.net.URLRequest; 
    import flash.net.URLRequestMethod; 
    import flash.net.URLVariables; 
 
    public class DownloadFileExample extends Sprite 
    { 
        private var fileToDownload:FileReference; 
        public function DownloadFileExample() 
        { 
            var request:URLRequest = new URLRequest(); 
            request.url = "http://www.[yourdomain].com/downloadfile.cfm"; 
            request.method = URLRequestMethod.GET; 
            request.data = new URLVariables("id=2"); 
            fileToDownload = new FileReference(); 
            try 
            { 
                fileToDownload.download(request, "file2.txt"); 
            } 
            catch (error:Error) 
            { 
                trace("Unable to download file."); 
            } 
        } 
    } 
}

下列程式碼將示範 ColdFusion 指令碼的 download.cfm 如何根據 URL 變數的值,從伺服器的兩個檔案中下載其中一個檔案:

<cfparam name="URL.id" default="1" /> 
<cfswitch expression="#URL.id#"> 
    <cfcase value="2"> 
        <cfcontent type="text/plain" file="#ExpandPath('two.txt')#" deletefile="No" /> 
    </cfcase> 
    <cfdefaultcase> 
        <cfcontent type="text/plain" file="#ExpandPath('one.txt')#" deletefile="No" /> 
    </cfdefaultcase> 
</cfswitch>

FileReferenceList 類別

FileReferenceList 類別可以讓使用者選取一個或多個檔案以上傳至伺服器端指令碼。檔案上傳作業是由 FileReference.upload() 方法處理,使用者所選取的每一個檔案都必須呼叫這個方法。

下列程式碼將建立兩個 FileFilter 物件 ( imageFilter textFilter ),並將它們以陣列形式傳遞給 FileReferenceList.browse() 方法。作業系統檔案對話方塊中就會顯示兩種類型的檔案篩選。

var imageFilter:FileFilter = new FileFilter("Image Files (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg; *.jpeg; *.gif; *.png"); 
var textFilter:FileFilter = new FileFilter("Text Files (*.txt, *.rtf)", "*.txt; *.rtf"); 
var fileRefList:FileReferenceList = new FileReferenceList(); 
try 
{ 
    var success:Boolean = fileRefList.browse(new Array(imageFilter, textFilter)); 
} 
catch (error:Error)  
{ 
    trace("Unable to browse for files."); 
}

雖然 FileReferenceList 類別允許您選取一個以上的檔案,但是使用 FileReferenceList 類別允許使用者選取並上傳一個或多個檔案,與使用 FileReference.browse() 選取檔案的方式並無不同。在上傳多個檔案時,您必須使用 FileReference.upload() 來上傳每一個選取的檔案,如下列程式碼所示:

var fileRefList:FileReferenceList = new FileReferenceList(); 
fileRefList.addEventListener(Event.SELECT, selectHandler); 
fileRefList.browse(); 
 
function selectHandler(event:Event):void 
{ 
    var request:URLRequest = new URLRequest("http://www.[yourdomain].com/fileUploadScript.cfm"); 
    var file:FileReference; 
    var files:FileReferenceList = FileReferenceList(event.target); 
    var selectedFileArray:Array = files.fileList; 
    for (var i:uint = 0; i < selectedFileArray.length; i++) 
    { 
        file = FileReference(selectedFileArray[i]); 
        file.addEventListener(Event.COMPLETE, completeHandler); 
        try 
        { 
            file.upload(request); 
        } 
        catch (error:Error) 
        { 
            trace("Unable to upload files."); 
        } 
    } 
} 
function completeHandler(event:Event):void 
{ 
    trace("uploaded"); 
}

由於已經將 Event.COMPLETE 事件加入陣列中的每一個 FileReference 物件,因此 Flash Player 會在完成每一項檔案上傳作業後呼叫 completeHandler() 方法。