Преобразование данных BSON, сохраненных в файле, в объект Javascript - PullRequest
1 голос
/ 27 апреля 2020

Я пытаюсь преобразовать файл BSON, сгенерированный сценарием python, в объект Javascript. Я использую https://www.npmjs.com/package/bson для пакета BSON и XMLHttpRequest для загрузки файла.

В случае, если это имеет значение, это моя блокировка пакета. json запись для bson.

        "bson": {
            "version": "4.0.4",
            "resolved": "https://registry.npmjs.org/bson/-/bson-4.0.4.tgz",
            "integrity": "sha512-Ioi3TD0/1V3aI8+hPfC56TetYmzfq2H07jJa9A1lKTxWsFtHtYdLMGMXjtGEg9v0f72NSM07diRQEUNYhLupIA==",
            "requires": {
                "buffer": "^5.1.0",
                "long": "^4.0.0"
            },
            "dependencies": {
                "buffer": {
                    "version": "5.6.0",
                    "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
                    "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
                    "requires": {
                        "base64-js": "^1.0.2",
                        "ieee754": "^1.1.4"
                    }
                }
            }
        }

Созданный файл основан на очень простой python программе

data = { 'key0': 'a', 'key1': [ 1, 2, 3 ], 'key2': 'b', 'key3': [ { 'k0': 'random', 'k1': 'string', 'k2': 'to use', 'k3': 3.145 }, { 'k0': 'other', 'k1': 'values', 'k2': 'here', 'k3': 0.0001}] }
with open('test.bson', 'wb') as fp:
    encoded = bson.encode(data)
    fp.write(encoded)

Пакет, используемый для python, равен pymongo (Версия 3.10 0,1).

ПРИМЕЧАНИЕ. Я обновил текст data. Первая версия работала нормально, когда я использовал решение Декеля. Тем не менее, мои фактические данные не работают. Я изменил его, и теперь он не работает с этой ошибкой:

Uncaught Error: buffer length 199 must === bson size 253
  deserialize$1 

Я могу загрузить файл, однако я не могу определить правильные вызовы BSON для использования в JS, чтобы передать это Javascript объект. Я встречаюсь с ошибками типа (требуется Buffer), ошибками переноса или исключениями.

Мой код выглядит следующим образом (в ответе используется deserialize Декеля).

import { deserialize } from 'bson'

let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = () => {
    if (xmlHttp.status == 200 && xmlHttp.readyState == 4) {
        const buf = Buffer.from(xmlHttp.responseText, 'binary');
        const dat = deserialize(buf, {});
        console.log(dat);
    }
};
xmlHttp.open("GET", 'assets/test.bson');
xmlHttp.send();

Если я не использовал {} в качестве второго аргумента deserialize, он генерирует его, что приводит к

 TS2554: Expected 2 arguments, but got 1

Я использую Webpack и Typescript для разработки.

Непонятно, могут ли данные быть неверными с точки зрения реализации JS BSON или если я неправильно вызываю JS BSON.

Я могу декодировать файл в python и bsondump также правильно декодирует файл.

Я создал репозиторий GitHub, в котором есть больше деталей, а также тестовые данные. https://github.com/mobileben/test-bson-js

Обнаружены некоторые другие детали.

  • При преобразовании в Buffer необходимо включить binary в качестве кодировки, иначе оно не будет работать правильно.
  • Это json (обратите внимание, что оно представлено как python dict) {"key3": [{"k0": "random", "k1": "string", "k2": "to use", "k3": 3.145}, {"k0": "other", "k1": "values", "k2": "here", "k3": 0.0001}]} приведет к тому, что Uncaught error, где размер не соответствует
  • Значения с плавающей запятой, при использовании dict, который не приведет к Uncaught error, имеют неправильное значение. Если я использую целочисленные значения, они в порядке.

За последний элемент

{"key3": {"k9": "here", "k0": 1, "k1": 2, "k2": 3}}

Будет работать. Это приводит (со стороны JS)

{"key3":{"k9":"here","k0":1,"k1":2,"k2":3}}

Однако

{"key3": {"k9": "here", "k0": 0.1, "k1": 0.2, "k2": 0.3}}

Результаты (со стороны JS)

{"key3":{"k9":"here","k0":1.8745098039215684,"k1":1.8745098039215684,"k2":1.825}}

Запуск bsondump в том же файле приводит к:

{"key3":{"k9":"here","k0":{"$numberDouble":"0.1"},"k1":{"$numberDouble":"0.2"},"k2":{"$numberDouble":"0.3"}}}

1 Ответ

1 голос
/ 27 апреля 2020

Если у вас есть содержимое файла в переменной data, вы можете использовать BSON lib следующим образом:

import { deserialize } from 'bson';
import data from '!!raw-loader!assets/test.bson'

console.log(deserialize(Buffer.from(data)))

Если вы используете xmlhttprequest:

import { deserialize } from 'bson';

let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = () => {
    if (xmlHttp.status == 200 && xmlHttp.readyState == 4) {
        console.log(deserialize(Buffer.from(xmlHttp.responseText)));
    }
};
xmlHttp.open("GET", 'assets/test.bson');
xmlHttp.send();
...