将Pickle对象转换成JS可读的代码?

问题描述 投票:0回答:3

我对 Pickle 库和 JS 还很陌生。我正在用 JS 编写代码来与 Python 服务器交互;当我向 Python 服务器发出 POST 时,我会返回一个腌制的浮点数。我想将 float 转换为 JS 可读的对象。

服务器返回类似

pickle.dumps(3.14159,0)
的内容。当我在 Python 中打印这个值时,我得到
b'F3.14159\n.'
但是,我正在使用的库 JPickle 无法解释返回中的“b”(或者至少,这就是我的猜测......当我尝试使用
console.log(jpickle.loads(response))
来取消我的响应,我收到“未处理的操作码”错误)。与 POST 请求分开,
jpickle.loads('F3.14159\n.')
给了我 3.14159,但是
jpickle.loads(b'F3.14159\n.')
无法编译。我不知道如何更改从 POST 获得的响应,因为它在 JS 中不可读,所以我不确定如何解决这个问题。

我对任何不涉及更改服务器端代码(我无法控制它)的解决方案持开放态度,包括使用另一个库。我尝试过 JsonPickle 但没有成功。

javascript pickle
3个回答
1
投票

仅使用 JSON,无需 pickle 库; Python 附带了

json
模块,浏览器 JS 可以开箱即用地将 json 解析为值。

通过类似

json.dump
的方式序列化您的数据,并在浏览器中使用
JSON.parse
对其进行反序列化。


0
投票

有点晚了,但附件中的答案可能会有所帮助::该代码允许浏览器上的 Javascript 通过 Ajax 遍历和解码来自 Python 的压缩 pickle 对象。

是否有已经发布的 Javascript 解决方案可以在不使用 Node.js 的情况下遍历 Python pickled 对象

确保 mime 类型允许您传递二进制数。


0
投票

这就是我在仪表板上使用它的方式。当点击某个按钮时,会启动加载动画,同时创建一个小的 json 字典“数据”并将其发送到在 Python 端(Flask)等待的 url '/dashboard/command'。 Python 回答“数据”中的问题,然后用二进制 blob 进行回复。我在 Flask 端强制执行 mimeType 时遇到了麻烦,所以在这里我作弊,只是告诉 javascript 它是一个 blob,无论 mimeType 说什么。

        const jqXHR = $.ajax({             // result is a Promise
            url:  '/dashboard/command',
            type: 'POST',
            data: data,
            contentType: 'application/json; charset=utf-8',
            xhr: function() {
               var xhr = new XMLHttpRequest();
               xhr.overrideMimeType('application/octet-stream; charset=x-user-defined');
               xhr.onreadystatechange = function () {
                  if (xhr.readyState == 2) {                 //HEADERS_RECEIVED = 2, time to update the responseType
                     if (xhr.status == 200) {
                        xhr.responseType = "blob";
                    } else {
                        xhr.responseType = "text";
                    }
                  }
                  if (xhr.readyState == 4) {                 //DONE = 4, what did we get?
                      if (xhr.status == 200) {
                        console.log(xhr.response instanceof Blob); // should be a blob
                    } else if (xhr.responseText != "") {
                        console.log(xhr.responseText);
                        alert(xhr.responseText);
                  }
               }
             };
            return xhr;
           }
          });

          jqXHR.done( function(data_msg) {
              console.log("Blob Received")
              $("#update-plot").prop('disabled', false);  // Re-enable button
              $("#update-plot-loading").addClass('invisible');  // Hide loading animation
              let blob = data_msg
              let reader = new FileReader();
              reader.onload = function(e) {              // binary data 
                  var blobdata = e.target.result
                  $("#update-plot").trigger('update', [blobdata, blobdata.byteLength]);   //will read the data and make plot, etc
              };
              reader.onerror = function(e) {             // error occurred
                  console.log('OnError : ' + e.type); 
              };
              reader.readAsArrayBuffer(blob);          // creates a readme promise based on the Ajax promise
          });

          jqXHR.fail( function(jqXHR, textStatus) {
              console.log("OnFail Textstatus:"+textStatus)
              target[0].prop('disabled', false);  // Re-enable button
              target[1].addClass('invisible');  // Hide loading spinner
              return(jqXHR.responseText)
          });

除了一个小细节之外,其他所有内容的代码都在之前的答案中。为了从压缩的 zlib 二进制文件中获取,我使用 Pako,它创建的是字符代码而不是字符串,所以我需要解压。

       const x = pako.inflate(binary_array)                      //  here goes

//       y = String.fromCharCode.apply(null, new Uint16Array(x)) - causes a stack overflow??!
// so we do it as a loop

       let x_str = []
       for (let i=0; i<x.length; i++) {
           x_str[i] = String.fromCharCode(x[i])
       }
       const updated_msg = x_str.join('');

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.