JavaScriptの値をローカルファイルに保存する方法について調べた2

はじめに

前回の続き。今回はユーザーにswfファイルをクリックさせて、JavaScriptの値をローカルファイルに保存するプログラムを書いてみました。

  • FireWrite.as
package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.external.ExternalInterface;
    import flash.net.FileReference;
    import mx.utils.Base64Decoder;

    public class WriteFile extends Sprite {
        function WriteFile () {
            // マウスクリックイベントを検出するとdoWrite()を呼び出すように登録する
            stage.addEventListener(MouseEvent.CLICK, doWrite);
        }

        private function doWrite (eventObj:MouseEvent):void {
            var fr:FileReference = new FileReference();
            var fileData:* = ExternalInterface.call("getFileData"); // 保存するファイル情報を取得する
            try {  // ローカルファイルに保存できるか試みる
                if (fileData["base64"]) {
                    // Base64エンコードされた文字列ならデコードして保存する
                    var b64d:Base64Decoder = new Base64Decoder();
                    b64d.decode(fileData["body"]);
                    fr.save(b64d.toByteArray(), fileData["name"]);
                } else {
                    // ただの文字列ならそのまま保存する
                    fr.save(fileData["body"], fileData["name"]);
                }
            } catch (error:Error) {
                // 保存できなければアラートを表示する
                ExternalInterface.call("function(){javascript:alert('だが断る " + error.message + "')}");
            }
        }
    }
}

このActionScriptではswfがユーザーにクリックされると、JSのgetFileData()関数を呼び出して保存したいファイルの情報を取得し、ASのFileReference.save()メソッドでファイルの保存を行っています。また、ただの文字列データを保存するだけだとおもしろくないので、Base64エンコードされた文字列はデコードしてバイナリファイルとして保存するようにしました。

上記のASファイルをコンパイルしてWriteFile.swfを作成し、これと同じ階層に以下のHTMLファイルを置いてWebブラウザーからアクセスします。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <script type="text/javascript">
            function getFileData () {
                return {"body"  : document.getElementById("fbody").value,
                        "name"  : document.getElementById("fname").value,
                        "base64": document.getElementById("chkbx").checked ? true : false}
            }
        </script>
    </head>
    <body>
        File Name : <input id="fname" type="text"><input id="chkbx" type="checkbox">Base64<br>
        <textarea id="fbody" cols="30" rows="5" wrap="soft"></textarea><br>
        <div style="position: relative;">
            <img src="button.png" style="position: absolute;"> <!-- 60x30 の画像 -->
            <div style="width: 60px; height: 30px; position: absolute;">
                <embed src="WriteFile.swf" name="wf" allowScriptAccess="always" width="100%" height="100%" wmode="transparent">
            </div>
        </div>
    </body>
</html>

このHTMLでは、保存ボタンを表す画像(button.png)の上にWriteFile.swfが重なるように並べています。Webブラウザーからアクセスすると以下のように表示されます。

適当にファイル名とメッセージを入力して保存ボタンの画像をクリックすると…

保存ダイアログが表示され、ローカルファイルとして保存する事ができます。また、バイナリファイルとして保存したいときは、

このようにBase64エンコードされた文字列を入力し、チェックボックスにチェックを飛ばして保存ボタンをクリックすると…

保存ダイアログが表示され、バイナリファイルとして保存することが出来ます。念のため確認すると、以下のように画像ファイルとして保存されていることが分かります。


おわりに

とりあえず、AS経由でJSの値をローカルファイルに保存することが出来ました。JSで出来ない事をASにさせるのは卑怯な感じがしますが、やりたかったことが出来たし、ASもちょっとだけ触れて満足です(^ω^)♪