Javascript 文件 API - Blob 到 JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12786818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:15:57  来源:igfitidea点击:

File API - Blob to JSON

javascriptjsonhtmlwebsocket

提问by Antonio

I'm trying to do some experiment with HTML5, WebSocket and File API. I'm using the Tomcat7 WebSocket implementation. I'm able to send and received text messages from the servlet. What I want to do now is to send from the servlet to the client JSON objects, but I want to avoid text message in order to skip the JSON.parse (or similar) on the client, so I'm trying to send binary messages. The servlet part is really simple:

我正在尝试对 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();

After this message, on the client I see that I received a binary frame, that is converted to a Blob object (http://www.w3.org/TR/FileAPI/#dfn-Blob). The question is: is it possible to get the JSON object from the Blob? I took a look at the FileReader interface (http://www.w3.org/TR/FileAPI/#FileReader-interface), and I used code like this to inspect what the FileReader can do (the first line creates a brand new Blob, so you can test on the fly if you want):

在此消息之后,在客户端上,我看到我收到了一个二进制帧,该帧已转换为 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);

using all the "readAs..." methods that I saw on the File Reader implementation (I'm using Chrome 22). Anyway I didn't find something useful.

使用我在文件阅读器实现中看到的所有“readAs...”方法(我使用的是 Chrome 22)。反正我没有找到有用的东西。

Did you have any suggestion? Thanks.

你有什么建议吗?谢谢。

采纳答案by saml

What you're doing is conceptually wrong. JSON is a string representation of an object, not an object itself. So, when you send a binary representation of JSON over the wire, you're sending a binary representation of the string. There's no way to get around parsing JSON on the client side to convert a JSON string to a JavaScript Object.

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

You absolutely should always send JSON as text to the client, and you should always call JSON.parse. Nothing else is going to be easy for you.

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

回答by qdev

You should have tried readAsText()instead of readAsArrayBuffer()(JSON is text in the end).

您应该尝试readAsText()而不是readAsArrayBuffer()(JSON 最后是文本)。

You've also missed to stringify the object (convert to JSON text)

您还没有对对象进行字符串化(转换为 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);

回答by sanshuiwang

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)