FileReference クラスを使用すると、クライアントコンピュータとサーバーとの間でファイルのアップロードおよびダウンロード機能を実現できます。ユーザーはダイアログボックス(Windows OS の「開く」ダイアログボックスなど)によって、アップロードするファイルやダウンロード先の場所を指定するよう要求されます。
ActionScript で作成した個々の FileReference オブジェクトは、ユーザーのハードディスク上にある同じファイルを参照します。このオブジェクトには、ファイルのサイズ、種類、名前、作成日および変更日の情報を格納するプロパティがあります。
FileReference クラスのインスタンスを作成する方法は 2 種類あります。1 つは、次のコードのように new 演算子を使用する方法です。
import flash.net.FileReference; var myFileReference:FileReference = new FileReference();
もう 1 つは、FileReferenceList.browse() メソッドを呼び出す方法です。このメソッドは、ユーザーのシステム上でダイアログボックスを開き、アップロードするファイルの指定(場合によっては複数)をユーザーに要求して、正常にファイルが指定されると FileReference オブジェクトの配列を作成します。個々の FileReference オブジェクトは、ユーザーがダイアログボックスで指定した 1 つのファイルを表します。FileReference オブジェクトに含まれる各種の FileReference プロパティ(name、size、modificationDate など)には、次のいずれかが行われるまでは何もデータが格納されていません。
FileReference.browse()、FileReferenceList.browse() または FileReference.download() のいずれかのメソッドに対する呼び出しの実行中は、ほとんどの Player で SWF の再生が続けられます。
FileReference クラスを使用すると、ユーザーのコンピュータとサーバーとの間でファイルのアップロードおよびダウンロード機能を実現できます。ユーザーに対してアップロードするファイルやダウンロード先の場所の指定を求めるために、OS のダイアログボックスを表示します。個々の FileReference オブジェクトはユーザーのディスク上にある 1 つのファイルを表し、ファイルのサイズ、タイプ、名前、作成日、変更日、クリエータに関する情報をプロパティとして保持します。
FileReference インスタンスを作成するには、次の 2 つの方法があります。
var myFileReference:FileReference = new FileReference();
アップロード処理およびダウンロード処理では、当該 SWF ファイル自体が属するドメイン内のファイルと、クロスドメインポリシーファイルで指定されたドメイン内のファイルに対してのみアクセスできます。アップロードまたはダウンロードを開始する SWF ファイルがファイルサーバーと同じドメインに属していない場合は、ファイルサーバー上にポリシーファイルを配置する必要があります。
ファイルのアップロードを処理するサーバースクリプトは、次の要素を含んだ 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 要求は、api_sig、api_key および auth_token という 3 つの 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--
サーバーにファイルをアップロードするには、まず browse() メソッドを呼び出して、ユーザーにファイルの選択を求めます。次に、FileReference.upload() メソッドが呼び出されると、選択されたファイルがサーバーへ転送されます。FileReferenceList.browse() メソッドで、ユーザーにより複数のファイルが選択された場合は、それらのファイルを表す FileReferenceList.fileList という配列が作成されます。その後、各ファイルを個別に FileReference.upload() メソッドでアップロードします。
デフォルトでは、ユーザーはシステムのファイルピッカーダイアログボックスを使用して、ローカルコンピュータ上にある任意のタイプのファイルを選択できます。ただし、次のように 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 アップロードファイルフィールド名を変更できます。前のコード例では、この操作の例としてデフォルト値の Filedata を Custom1 に置き換えています。
Flash Player のデフォルトではテストアップロードが試行されませんが、upload() メソッドの第 3 パラメータに true を指定するとこの動作を変更できます。テストアップロードの目的は、実際のファイルアップロードを正常に実行できるかどうか試すことと、(認証が必要な場合に)認証を通過できるかどうか確認することです。
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 クラスを使用すると、サーバーサイドスクリプトにアップロードするファイルをユーザーが指定できます。ファイルのアップロードについては、ユーザーが指定した個々のファイルに対して 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() メソッドが呼び出されます。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート