web-dev-qa-db-ja.com

ファイルAPI-JSONへのBlob

HTML5、WebSocket、およびFile APIを使って実験を試みています。私はTomcat7 WebSocket実装を使用しています。サーブレットからテキストメッセージを送受信できます。私が今したいのは、サーブレットからクライアントのJSONオブジェクトに送信することですが、クライアントでJSON.parse(または類似のもの)をスキップするためにテキストメッセージを避けたいので、バイナリメッセージを送信しようとしています。サーブレット部分は本当にシンプルです:

String s = "{arr : [1,2]}";
CharBuffer cbuf = CharBuffer.wrap(s);      
CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();      
getWsOutbound().writeBinaryMessage(encoder.encode(cbuf));
getWsOutbound().flush();

このメッセージの後、クライアントで、Blobオブジェクトに変換されたバイナリフレームを受信したことがわかります( http://www.w3.org/TR/FileAPI/#dfn-Blob ) 。問題は、BLOBからJSONオブジェクトを取得することは可能ですか?私はFileReaderインターフェイス( http://www.w3.org/TR/FileAPI/#FileReader-interface )を調べ、このようなコードを使用してFileReaderが実行できることを調べました(最初の行で新しいBlobが作成されるので、必要に応じてその場でテストできます)。

var b = new Blob([{"test": "toast"}], {type : "application/json"});
var fr = new FileReader();
fr.onload = function(evt) {
    var res = evt.target.result;
    console.log("onload",arguments, res, typeof res);
};
fr.readAsArrayBuffer(b);

ファイルリーダーの実装で見たすべての「readAs ...」メソッドを使用しています(Chrome 22を使用しています)。とにかく、何か便利なものは見つかりませんでした。

何か提案はありましたか?ありがとう。

17
Antonio

あなたがやっていることは概念的に間違っています。 JSONは、オブジェクト自体ではなく、オブジェクトの文字列表現です。つまり、JSONのバイナリ表現をネットワーク経由で送信すると、文字列のバイナリ表現が送信されます。クライアント側でJSONを解析してJSON文字列をJavaScriptオブジェクトに変換する方法はありません。

絶対に常にJSONをテキストとしてクライアントに送信し、常にJSON.parseを呼び出す必要があります。他に簡単なことはありません。

10
saml

readAsArrayBuffer()の代わりに readAsText() を試してみるべきでした(JSONは最後にテキストです)。

オブジェクトを文字列化することもできません(JSONテキストに変換)

var b = new Blob([JSON.stringify({"test": "toast"})], {type : "application/json"}),
    fr = new FileReader();

fr.onload = function() {
    console.log(JSON.parse(this.result))
};

fr.readAsText(b);
16
qdev
let reader = new FileReader()
      reader.onload = e => {
        if (e.target.readyState === 2) {
          let res = {}
          if (window.TextDecoder) {
            const enc = new TextDecoder('utf-8')
            res = JSON.parse(enc.decode(new Uint8Array(e.target.result))) //转化成json对象
          } else {
            res = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(e.target.result)))
          }

          console.info('import-back:: ', res)


        }
      }

      reader.readAsArrayBuffer(response)
1
sanshuiwang