1

私は、ユーザーが何かを設計して後で注文できる AS3 でプロジェクトを行っています。デザインは PDF、PNG、および XML にエクスポートされます。サーバーに保存したいこれらのファイル。MAMP ではすべてが機能し、HTTPStatus 200 が表示されます。MAMP から SWF を実行していますが、リモート サーバーで php-script に正常にアクセスされ、リモート サーバーにファイルが正常に書き込まれていることに注意してください。ただし、SWF をリモート サーバーにコピーすると、ファイルが保存されず、HTTPStatus 0 が返されます。

私が使用するクラス (以下の AS3 コードを参照) では、URLLoader を使用して次の 1 行の php スクリプトを取得します。

<?php file_put_contents($_POST['location'] . $_POST['fileName'], base64_decode($_POST['fileData']));

ここで AS3 クラス:

public class ServerConnection extends Sprite
{
    private var _files:Array = new Array();
    private var _fileNames:Array;
    private var _fileLocation:String = "";
    private var _scriptLocation:String;

    private var _fileSavesInProgress:Array = new Array();

    public function ServerConnection(scriptLocation:String = null, files:Array = null, fileNames:Array = null)
    {
        if (scriptLocation) setScriptLocation(scriptLocation);
        if (files) setFiles(files);
        if (fileNames) setFileNames(fileNames);
    }


    public function encodeFiles():void {
        for(var i:uint = 0; i < _files.length; i++) {
            _files[i] = encodeFile(_files[i]);
        }
    }
    public function encodeFile(byteArray:ByteArray):Base64Encoder {
        var base64:Base64Encoder = new Base64Encoder();
        base64.encodeBytes(byteArray);
        return base64;
    }

    public function saveFiles(location:String = null):void {
        if (location) setFileLocation(location);
        for(var i:uint = 0; i < _files.length; i++) {
            _files[i] = saveFile(_files[i], _fileNames[i]);
        }
    }
    public function saveFile(encodedFile:Base64Encoder, fileName:String = "test"):void {
        var data:URLVariables = new URLVariables();
        data.fileData = encodedFile;
        data.fileName = fileName;
        data.location = _fileLocation;
        this.dispatchEvent(new DebugEvent(DebugEvent.MESSAGE, "@serverConnection: a save file request was made for " + 
            fileName + "\n" +
            "url: " + _fileLocation + "\n" +
            " scriptLocation: " + _scriptLocation + "\n"
        ));

        var request:URLRequest = new URLRequest(_scriptLocation);
        request.method = URLRequestMethod.POST;
        request.data = data;

        var loader:URLLoader= new URLLoader();
        loader.addEventListener(Event.COMPLETE, function(e:Event):void {fileSaved(loader);});
        loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatus);
        loader.addEventListener(IOErrorEvent.IO_ERROR, ioError);
        _fileSavesInProgress.push(loader);

        try {
            loader.load(request);
        } catch (e:*) {
            this.dispatchEvent(new DebugEvent(DebugEvent.MESSAGE, "@serverConnection: error:* = " + e + " \n"));
        }

        //navigateToURL(request);
    }

    public function displayObjectToPNG(displayObject:*, scale:Number = 1):ByteArray {
        var bmpData:BitmapData=new BitmapData(displayObject.width, displayObject.height, true, 0xFFFFFF);
        bmpData.draw(displayObject);

        var byteArray:ByteArray = PNGEncoder.encode(bmpData);
        return byteArray;
    }

    public function xmlToByteArray(xml:XML):ByteArray {
        var byteArray:ByteArray = new ByteArray();
        byteArray.writeUTFBytes(xml);
        return byteArray;
    }

    public function setScriptLocation(url:String):void {
        _scriptLocation = url;
    }

    public function setFileLocation(url:String):void {
        _fileLocation = url;
    }

    public function setFiles(array:Array, encode:Boolean = true):void {
        for each(var file:* in array) {
            for each(var type:XML in describeType(file).extendsClass.@type) { 
                if (type == "flash.display::DisplayObject") file = displayObjectToPNG(file);
            }
            if (typeof(file) == "xml") {
                file =  xmlToByteArray(file);
            }

            _files.push(file);
        }
        if (encode) encodeFiles();
    }

    public function setFileNames(array:Array):void {
        _fileNames = array;
    }


    // EVENTS
    private function httpStatus(e:HTTPStatusEvent):void {
        this.dispatchEvent(new DebugEvent(DebugEvent.MESSAGE, "@serverConnection: status = " + e.status + " \n"));
    }

    private function ioError(e:IOErrorEvent):void {
        this.dispatchEvent(new DebugEvent(DebugEvent.MESSAGE, "@serverConnection: IOErrorID = " + e.errorID + "  Message: "+ e.text + " \n"));
    }

    private function fileSaved(loader:URLLoader):void {
        this.dispatchEvent(new DebugEvent(DebugEvent.MESSAGE, "@serverConnection: file save completed. " + (_fileSavesInProgress.length -1) + " files to go \n"));
        _fileSavesInProgress.splice(_fileSavesInProgress.indexOf(loader), 1);

        if (_fileSavesInProgress.length == 0) {
            filesSaved();
        }
    }

    private function filesSaved():void {
        this.dispatchEvent(new DebugEvent(DebugEvent.MESSAGE, "@serverConnection: files saved \n"));
        this.dispatchEvent (new ClassAttributesLoaded(ClassAttributesLoaded.CLASS_ATTRIBUTES_LOADED));
    }

}

私はこのように実装します

    var s:ServerConnection = new ServerConnection(
    CONSTANT.SAVE_FILE_SCRIPT_LOCATION, 
    [currentTemplate.getXML(), exampleTemplate, pdf.save(Method.LOCAL)], 
    [CONSTANT.PACKAGE_ID + ".xml", CONSTANT.PACKAGE_ID + ".png", CONSTANT.PACKAGE_ID + ".pdf"]
);
s.addEventListener(DebugEvent.MESSAGE, writeToDebug);
s.addEventListener(ClassAttributesLoaded.CLASS_ATTRIBUTES_LOADED, exit);
s.saveFiles(CONSTANT.RELATIVE_FILE_DIRECTORY);

loader.load(request); を変更すると ナビゲートするToURL(リクエスト); コードは機能します。ローカル サーバーとリモート サーバーで。明らかな理由から、この場合は navigateToURL を使用できません。navigateToURL が機能し、 loader.load(request) が問題について何も言っていないという事実は、私は思います...しかし、何ですか?

私はこれに固執していて、助けていただければ幸いです。前もって感謝します!

PS: テストのために、リモート DIR のアクセス許可を 777 に設定しました。さらに、前述のように、ファイルは MAMP からリモートに正常に保存されます。

4

1 に答える 1

1

解決

長い調査の結果、解決策を見つけました。次の crossdomain.xml を Web サーバーのルート (www.mysite.nl/) に追加します。

<?xml version="1.0" ?>

<cross-domain-policy>
    <site-control permitted-cross-domain-policies="master-only"/>
    <allow-access-from domain="*.mydomain.com" to-ports="*"/>
    <allow-http-request-headers-from domain="*.mydomain.com" headers="*"/>
</cross-domain-policy>

これは安全ではないため、このソリューションを使用する場合は、「mydomain.com」を許可する特定のドメインに変更してください。それで修正されました。

どうやって答えにたどり着いたか

次のコードを使用してエラーをキャッチできました。

loader.addEventListener(IOErrorEvent.IO_ERROR, handleSecurityError);

返されたエラーは次のとおりです: [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"]

通常、エラーには次の内容が含まれていることに注意してください。 a.swfはhttp://www.domain-b.com/url/file-b.swfからデータを読み込めません"]

このエラーは通常、セキュリティ ポリシーをロードすることで解決されます。セキュリティ ポリシーの使用方法については、次のリンクを参照してください: http://kb2.adobe.com/cps/142/tn_14213.html

ただし、この場合、アクセスされる URL は同じドメイン内にあります。(注: 同じフォルダ :D) したがって、最初は、他に連絡するドメインがないため、これは無関係だと思いました。しかし、一週間探した後、私はあまりにも絶望的になり、どうにかしてみました。

したがって、サーバーのルートに crossdomain.xml を追加すると問題が解決しました。

于 2012-08-14T18:49:42.970 に答える