Saving Binary Data with javascript changes bytes

Viewed 31

I have some binary data im trying to save to a file using javascript. The backend sending the data is written in python.

Here is the backend code for sending the binary data using flasks send_file:

def exportSavedata(characterId):
    character = Characters.query.filter_by(id=characterId, user_id=current_user.id).first()
    savedata = character.savedata
    
    exportFolder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'exportSavedata')
    if not os.path.isdir(exportFolder):
        os.mkdir(exportFolder)
    filename = f"{character.name}_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}.bin"
    filepath = os.path.join(exportFolder, filename)
    with open(filepath, 'wb') as f:
        f.write(savedata)
    return send_file(filepath)

The file python creates and sends:

63 6D 70 20 32 30 31 31 30 31 31 33 20 20 20 00    cmp.20110113....
00000010: 00 50 01 00 01 01 07 67 9A E4 FF 4B 65 79 72 6F    .P.....g.d.Keyro
00000020: 69 69 00 4D BE 32 23 00 01 7D EF 35 00 01 C1 FF    ii.M>2#..}o5..A.
00000030: 40 01 00 01 80 80 00 02 08 00 01 08 00 0A 58 70    @.............Xp
00000040: 01 00 0E 18 24 20 00 04 1C 00 0B 04 00 01 01 01    ....$...........
00000050: 80 00 03 80 03 00 02 30 08 00 13 AD C7 C0 13 00    .......0...-G@..
00000060: 02 40 00 01 30 33 08 A0 03 01 1E 08 01 00 01 01    .@..03..........
00000070: 00 01 04 01 06 9C 00 0D 01 06 F6 00 0D 01 06 1C    ..........v.....
00000080: 00 0D 01 06 88 02 00 0C 01 06 63 00 0D 01 06 1E    ..........c.....
00000090: 02 00 0C 01 06 7F 00 0D 01 06 0C 02 00 0C 01 07    ................
000000a0: 01 00 0D 01 07 0D 00 0D 01 07 6C 00 0D 01 02 C4    ..........l....D
000000b0: 0E 01 00 0B 01 03 A5 0C 00 0C 01 04 A0 0C 00 0C    ......%.........
000000c0: 01 05 3A 0D 00 0C 01 00 01 A0 0C 00 0C 01 02 F3    ..:............s
[...]

The frontend code saving the file:

downloadSavefile(){
            axios.get("http://127.0.0.1:5000/export/" + this.characterData.id)
                .then(response => {
                    const a = document.createElement("a");
                    const blob = new Blob([response.data], { type: "octet/stream" });
                    const url = window.URL.createObjectURL(blob);
                    a.href = url;
                    a.download = this.characterData.name + ".bin";
                    a.click();
                    window.URL.revokeObjectURL(url);
                })
        },

The file javascript creates:

63 6D 70 20 32 30 31 31 30 31 31 33 20 20 20 00    cmp.20110113....
00000010: 00 50 01 00 01 01 07 67 EF BF BD EF BF BD EF BF    .P.....go?=o?=o?
00000020: BD 4B 65 79 72 6F 69 69 00 4D EF BF BD 32 23 00    =Keyroii.Mo?=2#.
00000030: 01 7D EF BF BD 35 00 01 EF BF BD EF BF BD 40 01    .}o?=5..o?=o?=@.
00000040: 00 01 EF BF BD EF BF BD 00 02 08 00 01 08 00 0A    ..o?=o?=........
00000050: 58 70 01 00 0E 18 24 20 00 04 1C 00 0B 04 00 01    Xp....$.........
00000060: 01 01 EF BF BD 00 03 EF BF BD 03 00 02 30 08 00    ..o?=..o?=...0..
00000070: 13 EF BF BD EF BF BD EF BF BD 13 00 02 40 00 01    .o?=o?=o?=...@..
00000080: 30 33 08 EF BF BD 03 01 1E 08 01 00 01 01 00 01    03.o?=..........
00000090: 04 01 06 EF BF BD 00 0D 01 06 EF BF BD 00 0D 01    ...o?=....o?=...
000000a0: 06 1C 00 0D 01 06 EF BF BD 02 00 0C 01 06 63 00    ......o?=.....c.
000000b0: 0D 01 06 1E 02 00 0C 01 06 7F 00 0D 01 06 0C 02    ................
000000c0: 00 0C 01 07 01 00 0D 01 07 0D 00 0D 01 07 6C 00    ..............l.
[...]

As you can see some of the bytes change somewhere inbetween sending it from the backend and saving the file in the frontend. I initially saved the file using the file-saver npm package but trying to find out the root cause I switched to a vanilla javascript solution which sadly did not solve the problem.

Thanks in advance for any help.

1 Answers

You can have Axios treat the response data directly as a Blob by passing in { responseType: 'blob' } as a second argument to your .get() call.

Try then setting const url = window.URL.createObjectURL(response.data); instead.

Related