Я пытаюсь преобразовать файл 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"}}}