ファイルのアップロードおよびダウンロード操作

FileReference クラスを使用すると、クライアントとサーバー間におけるファイルのアップロード機能とダウンロード機能を追加することができます。ユーザーはダイアログボックス (Windows OS の [開く] ダイアログボックスなど) によって、アップロードするファイルやダウンロード先の場所を指定するよう要求されます。

ActionScript で作成した個々の FileReference オブジェクトは、ユーザーのハードディスク上にある同じファイルを参照します。このオブジェクトには、ファイルのサイズ、種類、名前、作成日、および変更日の情報を格納するプロパティがあります。

メモ

 

creator プロパティは Mac OS でのみサポートされており、その他すべてのプラットフォームでは null を返します。

FileReference クラスのインスタンスを作成する方法は 2 種類あります。1 つは、次のコードのように new 演算子を使用する方法です。

import flash.net.FileReference;
var myFileReference:FileReference = new FileReference();

あるいは、FileReferenceList.browse() メソッドを呼び出すこともできます。このメソッドは、アップロードするファイルの選択用ダイアログボックスをユーザーのシステム上で開き、ユーザーがファイルを正常に選択すると FileReference オブジェクトの配列を作成します。個々の FileReference オブジェクトは、ユーザーがダイアログボックスで指定した 1 つのファイルを表します。FileReference オブジェクトに含まれる各種の FileReference プロパティ (namesizemodificationDate など) には、次のいずれかが行われるまでは何もデータが格納されていません。

メモ

 

ダウンロードを実行する場合、FileReference.name プロパティだけはダウンロードの完了より前に設定されます。ダウンロードが完了すると、すべてのプロパティの値が設定されます。

FileReference.browse()FileReferenceList.browse()FileReference.download() いずれかのメソッドに対する呼び出しの実行中、ほとんどの Player では SWF の再生が続けられます。

サブトピック

FileReference クラス
サーバーへのファイルのアップロード
サーバーからのファイルのダウンロード
FileReferenceList クラス

FileReference クラス

FileReference クラスを使用すると、ユーザーのコンピュータとサーバーとの間でファイルのアップロードおよびダウンロード機能を実現できます。ユーザーに対してアップロードするファイルやダウンロード先の場所の指定を求めるために、OS のダイアログボックスを表示します。個々の FileReference オブジェクトはユーザーのディスク上にある 1 つのファイルを表し、ファイルのサイズ、タイプ、名前、作成日、変更日、クリエータに関する情報をプロパティとして保持します。

FileReference インスタンスを作成するには、次の 2 つの方法があります。

アップロード処理およびダウンロード処理では、当該 SWF ファイル自体が属するドメイン内のファイルと、クロスドメインポリシーファイルで指定されたドメイン内のファイルに対してのみアクセスできます。アップロードまたはダウンロードを開始する SWF ファイルがファイルサーバーと同じドメインに属していない場合は、ファイルサーバー上にポリシーファイルを配置する必要があります。

メモ

 

browse() または download() のアクションを複数並行して実行することはできません。これは、一度に 1 つしかダイアログボックスを表示できないためです。

ファイルのアップロードを処理するサーバースクリプトは、次の要素を含んだ HTTP POST リクエストを受け付ける必要があります。

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 要求は、3 つの POST 変数を送信します。つまり、api_sigapi_key、および auth_token です。この例では、カスタムアップロードデータフィールド名の値は、"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--

サーバーへのファイルのアップロード

サーバーにファイルをアップロードするには、まず browse() メソッドを呼び出して、ユーザーにファイルの選択を求めます。次に、FileReference.upload() メソッドが呼び出されると、選択したファイルがサーバーに転送されます。ユーザーが FileReferenceList.browse() メソッドを使用して複数のファイルを選択した場合、Flash Player は FileReferenceList.fileList と呼ばれる選択されたファイルの配列を作成します。その後、各ファイルを個別に FileReference.upload() メソッドでアップロードします。

メモ

 

FileReference.browse() メソッドを使用する場合は、ファイルを 1 つだけアップロードできます。複数のファイルをアップロードできるようにするには、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() メソッドを使用してファイルをアップロードする場合は、次のコードで Web サーバーにファイルを送信する必要があります。

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() メソッドを使用してファイルをアップロードしようとする際には、次のイベントが送出されることがあります。

ヒント

 

認証を必要とするサーバーに対する Flash Player のサポートは完全ではありません。認証用のユーザー名とパスワードを入力するダイアログボックスを表示できるのは、ブラウザプラグインまたは Microsoft ActiveX® コントロールを使用してブラウザ上で実行される SWF ファイルにおいて、ダウンロードを実行する場合のみです。プラグインまたは ActiveX コントロールを使用する場合のアップロードと、スタンドアローン Player または外部 Player を使用する場合のアップロードおよびダウンロードでは、ファイル転送に失敗します。

Flash Player によるファイルのアップロードを受け付けるスクリプトを ColdFusion で作成する場合は、次のようなコードを使用します。

<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 (GET メソッドの場合) または URLRequestMethod.POST (POST メソッドの場合) を設定します。

また、ActionScript 3.0 では、upload() メソッドの第 2 パラメータを指定することで、デフォルトの Filedata アップロードファイルフィールド名を変更できます。前のコード例では、この操作の例としてデフォルト値の FiledataCustom1 に置き換えています。

Flash Player のデフォルトではテストアップロードが試行されませんが、upload() メソッドの第 3 パラメータに true を指定するとこの動作を変更できます。テストアップロードの目的は、実際のファイルアップロードを正常に実行できるかどうか試すことと、(認証が必要な場合に) 認証を通過できるかどうか確認することです。

メモ

 

テストアップロードは、現在のところ Windows 版の各種 Flash Player でのみ実行されます。

サーバーからのファイルのダウンロード

FileReference.download() メソッドを使用すると、サーバー上のファイルをユーザーがダウンロードできます。このメソッドには、request および defaultFileName の 2 つのパラメータがあります。第 1 パラメータには、ダウンロードするファイルの URL を表す URLRequest オブジェクトを指定します。第 2 パラメータはオプションです。ダウンロードファイルのダイアログボックスに表示されるデフォルトのファイル名を指定できます。第 2 パラメータの 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.");
            }
        }
    }
}

次のコードは "download.cfm" という ColdFusion スクリプトの例です。URL 変数の値に応じて、サーバー上にある 2 つのファイルのうちいずれかをダウンロードします。

<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() メソッドを呼び出すことにより処理する必要があります。

次のコードでは、2 つの FileFilter オブジェクト (imageFilter および textFilter) を作成し、それらを配列として FileReferenceList.browse() メソッドに渡しています。これにより、OS のファイルダイアログボックスにはファイルタイプを指定するフィルタが 2 つ表示されます。

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 クラスを使用して複数のファイルを選択およびアップロードできるようにする場合も、ファイルの選択は 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");
}

配列内の各 FileReference オブジェクトに対して Event.COMPLETE イベントを登録しているため、各ファイルのアップロードが完了するたびに、Flash Player によって completeHandler() メソッドが呼び出されます。


 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000320.html