1

node.jsをいじくり回して、クライアント側でファイルをチャンクし、socket.ioを介してサーバーにピースを送信し、再アセンブルするファイルアップローダーを機能させようとしています。これはかなり単純な実装ですが、学習しようとしているだけです。現在、テキストファイルを送信すると、移動して正しく再構築されますが、たとえば画像ファイルをアップロードしようとすると、エンコーディングが混乱し、ファイルが破損します。

クライアント側でバイナリ文字列として読み取っていますが、ノードのfsエンコーディングがバイナリに設定されています。他に何が起こる必要がありますか?

クライアントコード

while(start < fileSize)
{
    var reader = new FileReader();
    reader.onload = function(e){
        var data = {
            "data" : e.target.result,
            "sequence" : chunkCount++
        };
        socket.emit("sendChunk", data, function(data){
            console.log("Confirmation recieved");
        });
        console.log("Log: Sent");
    };

    reader.onerror = function(e){
        alert(e.getMessage());
    };

    var blob = file.slice(start, end);
    reader.readAsBinaryString(blob);
    start = end;
    end = end + chunkSize;

}

サーバーコード

socket.on('sendChunk', function (data) {
    fs.appendFileSync(path + fileName, data.data, 'binary');
    console.log(data.sequence + ' - The data was appended to file ' + fileName);
});

アップデート

与えられた提案で、base64デコードを使用するようにコードを更新しました。シーケンスの問題がまだ発生することがありますが、ほとんどの場合、ファイルは正しく転送されています。

クライアントコード:

var data = {
    "data" : window.btoa(e.target.result),
    "sequence" : chunkCount++
};
socket.emit("sendChunk", data, function(data){
    console.log("Confirmation recieved");
});

サーバーコード:

var decoded =  new Buffer(data.data, 'base64').toString('binary');
fs.appendFileSync(path + fileName, decoded, 'binary');
4

1 に答える 1

3

socket.emit()JavaScriptで記述されているため、ペイロードはJavaScriptとして扱われますString。JavaScriptでは文字列がUCS-2で表され、特定の制御文字がエスケープされているため、サーバー上で文字化けしたデータを受信して​​います。つまり、JavaScript文字列はArrayバイトサイズの文字ではなく、バイナリデータの保存や転送には適していません。

画像を送信する最も安全な方法は、クライアントでバイナリデータをbase64としてエンコードし、サーバーでBufferクラスを使用してデコードすることです。

于 2013-02-18T17:13:41.747 に答える