JSON.stringify or how to serialize binary data as base64 encoded JSON?
Asked Answered
W

2

5

I have a Javascript object which will consists of a non-cyclic object hierarchy with parameters and child objects. Some of these objects may hold binary data loaded from files or received via XHRs (not defined yet if Blob, ArrayBuffer or something else).

Normally I would use JSON.stringify() to serialize it as JSON but how can I then specify that binary data will be base64 encoded?

What binary data object (Blob, ArrayBuffer,...) would you recommend me then?

EDIT: Other data formats than plain JSON is not an option.

Wellgroomed answered 1/12, 2014 at 16:20 Comment(1)
JSON.stringify accepts a second argument with which you can define your own conversion for specific values: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Wittenberg
U
9

For blobs it makes more sense to convert the Blobs in the object to base64 beforehand and then stringify the object. This is because there is no reliable way to synchronously convert a blob to base64, and thus the replacer function is not a viable choice here.

const blobToBase64 = (blob) => {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onloadend = function () {
      resolve(reader.result);
    };
  });
};

(async () => {
  const b64 = await blobToBase64(blob);
  const jsonString = JSON.stringify({blob: b64});
  console.log(jsonString);
})();

Getting a blob from parsed JSON is then as simple as

const parsed = JSON.parse(jsonString);
const blob = await fetch(parsed.blob).then(res => res.blob());
console.log(blob);
Uball answered 12/5, 2020 at 5:40 Comment(0)
W
0

JSON.stringify indeed did the trick with two possible solutions:

a) The replacer function called to decide how to serialize a value.

function replacer(key, value) {
  if (typeof value === "string") {
    return undefined;
  }
  return value;
}

var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};

var jsonString = JSON.stringify(foo, replacer);

b) Define a toJSON() member function for the object.

var obj = {
  foo: 'foo',
  toJSON: function () {
    return '{ "foo": "' +  + '" }';
  }
};
JSON.stringify(obj);      // '{ "foo": "Zm9v" }'

Plz up this comment instead if that works for you, too.

Wellgroomed answered 24/1, 2015 at 15:23 Comment(2)
How is this answers the question?Travers
So where does the base64 enter into your solution?Precipitate

© 2022 - 2024 — McMap. All rights reserved.