29

我正在尝试用 HTML5、WebSocket 和 File API 做一些实验。我正在使用 Tomcat7 WebSocket 实现。我能够从 servlet 发送和接收文本消息。我现在要做的是从 servlet 发送到客户端 JSON 对象,但我想避免文本消息以跳过客户端上的 JSON.parse (或类似的),所以我试图发送二进制消息. servlet 部分非常简单:

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)。反正我没有找到有用的东西。

你有什么建议吗?谢谢。

4

4 回答 4

31

您应该尝试使用 readAsText()而不是readAsArrayBuffer()(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);
于 2017-09-04T15:41:33.373 回答
12

你所做的在概念上是错误的。JSON 是对象的字符串表示形式,而不是对象本身。因此,当您通过网络发送 JSON 的二进制表示时,您发送的是字符串的二进制表示。无法绕过在客户端解析 JSON 以将 JSON 字符串转换为 JavaScript 对象。

您绝对应该始终将 JSON 作为文本发送到客户端,并且您应该始终调用 JSON.parse。对你来说,没有什么是容易的。

于 2012-10-08T20:45:23.547 回答
4

要将包含 JSON 数据的Blob/转换为 JavaScript 对象,请使用它:File

JSON.parse(await blob.text());

这个例子:

选择一个 JSON 文件,然后你可以在浏览器的控制台(json对象)中使用它。

const input = document.createElement("input");
input.type = "file";
input.accept = "application/json";
document.body.append(input);
input.addEventListener("change", async event => {
    const json = JSON.parse(await input.files[0].text());

    console.log("json", json);
    globalThis.json = json;
});

于 2021-05-11T01:09:36.473 回答
1
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)
于 2019-04-13T08:27:34.380 回答