javascript - How do I encode a "raw" image import in Vite to Base64? - Stack Overflow

admin2025-04-04  1

I have a JPG that I import in Vite like import data from "whatever.jpg?raw";. My goal is to encode the resulting raw JPEG string as a data URI like data:image/jpeg;base64,DATA. The JPEG is very small (20x13, 1 KB), so size shouldn't be an issue. The problem is that I can't figure out how to get the correct output.

My idea for what the "correct" output should look like es from running the JPEG through , and I've been able to verify that my browser correctly renders that output. Here it is:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABSgAwAEAAAAAQAAAA0AAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIAA0AFAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/3QAEAAL/2gAMAwEAAhEDEQA/APTvil+2F4gb4MMll4P1Pwhq93DbmbVo7yC6hti0oVhGEYSEHkCRlQAHccCsz9j347eFPC4vZLHWm1GHVnQawlwI4kbUVCotxHKSTmQYVw7lF2ptwxbd4JoXj7VPFMGp6dqd7fXEWqCOK/zdE/akC7VV9wPAUBcAgY7Vuz+CfD2i2uoQ2+kxzR3qi3uUu5HmSVScnKk47nIAwa+Jnm3J8bbn00Vunm/608zopzUIuDimn959geKP2v7TStauLSL4V+N79YjtM8UNsqsR1xmX9ayv+G0IP+iP+O/+/dp/8dr4813WdV+2hU1zWI40QKkaalMAijgADd0rO/tfV/8AoP61/wCDOf8A+Kq1mlR/b/8AJf8A7Y42tdF/X3H/2Q==

I've also found that I can get that output back to the original string with this one-liner:

await (await (await fetch(output)).blob()).text();

So I've got an output "target" that I know I should be getting, and you have a way to see the original string. So let me explain what I've tried that isn't working.

1. btoa()

My project is an SSR project which will run on Cloudflare Workers, so I need to be careful that any functions I use are isomorphic. Since this function is marked as (deprecated) in Node.js, I'd rather find another way to do this, but I tried it anyways. After running btoa(data) I got this error:

Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
    at <anonymous>:1:1

After some searching, I read that the solution is to instead do btoa(unescape(encodeURIComponent(data))):

77+977+977+977+9ABBKRklGAAEBAABIAEgAAO+/ve+/vQDvv71FeGlmAABNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAA77+9aQAEAAAAAQAAAFoAAAAAAAAASAAAAAEAAABIAAAAAQAD77+9AQADAAAAAQABAADvv70CAAQAAAABAAAAFO+/vQMABAAAAAEAAAANAAAAAO+/ve+/vQA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDvv70d77+92Y8A77+9BO+/vQnvv73vv73vv71Cfu+/ve+/vQARCAANABQDASIAAhEBAxEB77+977+9AB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC++/ve+/vQDvv70QAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQy77+977+977+9CCNC77+977+9FVLvv73vv70kM2Jy77+9CQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eu+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/vQAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgvvv73vv70A77+9EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy77+9CBRC77+977+977+977+9CSMzUu+/vRVicu+/vQoWJDTvv70l77+9FxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXrvv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv70AQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU77+977+9AEMBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFO+/ve+/vQAEAALvv73vv70ADAMBAAIRAxEAPwDvv73vv71f77+9F++/vRvvv73vv70l77+977+977+9Pwhq77+9cNuZ77+9aO+/vSDvv73vv73YtO+/vVhGEe+/ve+/vR5A77+977+9AAdx77+977+977+977+977+947eFPC4vZO+/vdabUe+/vVZ0Gu+/vVwI77+9Ru+/vVQqLe+/vXLvv71OZBhXDu+/vRdqbe+/vRbvv73vv73vv70X77+977+9TxTvv73vv73vv73ane+/ve+/ve+/vVrvv73vv70r77+977+9E++/ve+/vQvvv71V77+9A++/vVAXAO+/ve+/vdW7P++/vXw977+977+977+9EO+/ve+/vTHvv70d77+9e++/ve+/ve+/ve+/vUlU77+977+977+9OO+/vXIA77+977+977+977+9be+/ve+/ve+/ve+/vUVu77+9b++/ve+/ve+/ve+/vTUI77+9OO+/ve+/ve+/vX3vv73vv73vv73vv73vv71K1q4tIu+/vVfvv71777+977+977+9M++/vQ3vv73vv70R77+9Ge+/ve+/ve+/ve+/ve+/vW0IP++/ve+/ve+/ve+/ve+/ve+/vX/vv73vv73vv73vv71d77+9dV/vv73vv71Nc1jvv700QO+/vRpqUwDvv704AA3vv70rO++/vV9X77+9AO+/ve+/ve+/ve+/vQDvv70577+9AO+/ve+/ve+/ve+/vVR/b++/vQAl77+9AO+/vTbvv73vv71/X3Hvv73vv70=

However, as you can see, the output is wrong. I'm expecting some string like /9j/4AAQSk...F/X3H/2Q== based on the "correct" output above, but this string is like 77+977+977...Hvv73vv70=. Not at all the same.

2. js-base64

Let's try using a library. Here's what I tried:

import { toBase64 } from "js-base64";

toBase64(data);

However, I get the same incorrect output above. The library does have a urlsafe argument, though, so I tried that too:

toBase64(data, true);

But that doesn't get me the right output either. I end up with this:

77-977-977-977-9ABBKRklGAAEBAABIAEgAAO-_ve-_vQDvv71FeGlmAABNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAA77-9aQAEAAAAAQAAAFoAAAAAAAAASAAAAAEAAABIAAAAAQAD77-9AQADAAAAAQABAADvv70CAAQAAAABAAAAFO-_vQMABAAAAAEAAAANAAAAAO-_ve-_vQA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDvv70d77-92Y8A77-9BO-_vQnvv73vv73vv71Cfu-_ve-_vQARCAANABQDASIAAhEBAxEB77-977-9AB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC--_ve-_vQDvv70QAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQy77-977-977-9CCNC77-977-9FVLvv73vv70kM2Jy77-9CQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eu-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_vQAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgvvv73vv70A77-9EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy77-9CBRC77-977-977-977-9CSMzUu-_vRVicu-_vQoWJDTvv70l77-9FxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXrvv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv70AQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU77-977-9AEMBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFO-_ve-_vQAEAALvv73vv70ADAMBAAIRAxEAPwDvv73vv71f77-9F--_vRvvv73vv70l77-977-977-9Pwhq77-9cNuZ77-9aO-_vSDvv73vv73YtO-_vVhGEe-_ve-_vR5A77-977-9AAdx77-977-977-977-977-947eFPC4vZO-_vdabUe-_vVZ0Gu-_vVwI77-9Ru-_vVQqLe-_vXLvv71OZBhXDu-_vRdqbe-_vRbvv73vv73vv70X77-977-9TxTvv73vv73vv73ane-_ve-_ve-_vVrvv73vv70r77-977-9E--_ve-_vQvvv71V77-9A--_vVAXAO-_ve-_vdW7P--_vXw977-977-977-9EO-_ve-_vTHvv70d77-9e--_ve-_ve-_ve-_vUlU77-977-977-9OO-_vXIA77-977-977-977-9be-_ve-_ve-_ve-_vUVu77-9b--_ve-_ve-_ve-_vTUI77-9OO-_ve-_ve-_vX3vv73vv73vv73vv73vv71K1q4tIu-_vVfvv71777-977-977-9M--_vQ3vv73vv70R77-9Ge-_ve-_ve-_ve-_ve-_vW0IP--_ve-_ve-_ve-_ve-_ve-_vX_vv73vv73vv73vv71d77-9dV_vv73vv71Nc1jvv700QO-_vRpqUwDvv704AA3vv70rO--_vV9X77-9AO-_ve-_ve-_ve-_vQDvv70577-9AO-_ve-_ve-_ve-_vVR_b--_vQAl77-9AO-_vTbvv73vv71_X3Hvv73vv70

3. Buffer.from(data).toString("base64")

Even though this is a Node.js API and doesn't work in my browser, I gave it a try wrapping it in if (import.meta.env.SSR), but I get the same 77+977+977...Hvv73vv70= output from above.

So what am I missing here? How do I get the correct Base64 output? I tried taking the "incorrect" output I got and correctly prefixing it with data:image/jpeg;base64,, but not surprisingly the browser doesn't render it. What do I need to do to get the same "correct" output which I got when running the image through ?

I have a JPG that I import in Vite like import data from "whatever.jpg?raw";. My goal is to encode the resulting raw JPEG string as a data URI like data:image/jpeg;base64,DATA. The JPEG is very small (20x13, 1 KB), so size shouldn't be an issue. The problem is that I can't figure out how to get the correct output.

My idea for what the "correct" output should look like es from running the JPEG through https://www.base64-image.de, and I've been able to verify that my browser correctly renders that output. Here it is:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABSgAwAEAAAAAQAAAA0AAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIAA0AFAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/3QAEAAL/2gAMAwEAAhEDEQA/APTvil+2F4gb4MMll4P1Pwhq93DbmbVo7yC6hti0oVhGEYSEHkCRlQAHccCsz9j347eFPC4vZLHWm1GHVnQawlwI4kbUVCotxHKSTmQYVw7lF2ptwxbd4JoXj7VPFMGp6dqd7fXEWqCOK/zdE/akC7VV9wPAUBcAgY7Vuz+CfD2i2uoQ2+kxzR3qi3uUu5HmSVScnKk47nIAwa+Jnm3J8bbn00Vunm/608zopzUIuDimn959geKP2v7TStauLSL4V+N79YjtM8UNsqsR1xmX9ayv+G0IP+iP+O/+/dp/8dr4813WdV+2hU1zWI40QKkaalMAijgADd0rO/tfV/8AoP61/wCDOf8A+Kq1mlR/b/8AJf8A7Y42tdF/X3H/2Q==

I've also found that I can get that output back to the original string with this one-liner:

await (await (await fetch(output)).blob()).text();

So I've got an output "target" that I know I should be getting, and you have a way to see the original string. So let me explain what I've tried that isn't working.

1. btoa()

My project is an SSR project which will run on Cloudflare Workers, so I need to be careful that any functions I use are isomorphic. Since this function is marked as (deprecated) in Node.js, I'd rather find another way to do this, but I tried it anyways. After running btoa(data) I got this error:

Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
    at <anonymous>:1:1

After some searching, I read that the solution is to instead do btoa(unescape(encodeURIComponent(data))):

77+977+977+977+9ABBKRklGAAEBAABIAEgAAO+/ve+/vQDvv71FeGlmAABNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAA77+9aQAEAAAAAQAAAFoAAAAAAAAASAAAAAEAAABIAAAAAQAD77+9AQADAAAAAQABAADvv70CAAQAAAABAAAAFO+/vQMABAAAAAEAAAANAAAAAO+/ve+/vQA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDvv70d77+92Y8A77+9BO+/vQnvv73vv73vv71Cfu+/ve+/vQARCAANABQDASIAAhEBAxEB77+977+9AB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC++/ve+/vQDvv70QAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQy77+977+977+9CCNC77+977+9FVLvv73vv70kM2Jy77+9CQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eu+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/vQAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgvvv73vv70A77+9EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy77+9CBRC77+977+977+977+9CSMzUu+/vRVicu+/vQoWJDTvv70l77+9FxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXrvv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv70AQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU77+977+9AEMBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFO+/ve+/vQAEAALvv73vv70ADAMBAAIRAxEAPwDvv73vv71f77+9F++/vRvvv73vv70l77+977+977+9Pwhq77+9cNuZ77+9aO+/vSDvv73vv73YtO+/vVhGEe+/ve+/vR5A77+977+9AAdx77+977+977+977+977+947eFPC4vZO+/vdabUe+/vVZ0Gu+/vVwI77+9Ru+/vVQqLe+/vXLvv71OZBhXDu+/vRdqbe+/vRbvv73vv73vv70X77+977+9TxTvv73vv73vv73ane+/ve+/ve+/vVrvv73vv70r77+977+9E++/ve+/vQvvv71V77+9A++/vVAXAO+/ve+/vdW7P++/vXw977+977+977+9EO+/ve+/vTHvv70d77+9e++/ve+/ve+/ve+/vUlU77+977+977+9OO+/vXIA77+977+977+977+9be+/ve+/ve+/ve+/vUVu77+9b++/ve+/ve+/ve+/vTUI77+9OO+/ve+/ve+/vX3vv73vv73vv73vv73vv71K1q4tIu+/vVfvv71777+977+977+9M++/vQ3vv73vv70R77+9Ge+/ve+/ve+/ve+/ve+/vW0IP++/ve+/ve+/ve+/ve+/ve+/vX/vv73vv73vv73vv71d77+9dV/vv73vv71Nc1jvv700QO+/vRpqUwDvv704AA3vv70rO++/vV9X77+9AO+/ve+/ve+/ve+/vQDvv70577+9AO+/ve+/ve+/ve+/vVR/b++/vQAl77+9AO+/vTbvv73vv71/X3Hvv73vv70=

However, as you can see, the output is wrong. I'm expecting some string like /9j/4AAQSk...F/X3H/2Q== based on the "correct" output above, but this string is like 77+977+977...Hvv73vv70=. Not at all the same.

2. js-base64

Let's try using a library. Here's what I tried:

import { toBase64 } from "js-base64";

toBase64(data);

However, I get the same incorrect output above. The library does have a urlsafe argument, though, so I tried that too:

toBase64(data, true);

But that doesn't get me the right output either. I end up with this:

77-977-977-977-9ABBKRklGAAEBAABIAEgAAO-_ve-_vQDvv71FeGlmAABNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAA77-9aQAEAAAAAQAAAFoAAAAAAAAASAAAAAEAAABIAAAAAQAD77-9AQADAAAAAQABAADvv70CAAQAAAABAAAAFO-_vQMABAAAAAEAAAANAAAAAO-_ve-_vQA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDvv70d77-92Y8A77-9BO-_vQnvv73vv73vv71Cfu-_ve-_vQARCAANABQDASIAAhEBAxEB77-977-9AB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC--_ve-_vQDvv70QAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQy77-977-977-9CCNC77-977-9FVLvv73vv70kM2Jy77-9CQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eu-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_ve-_vQAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgvvv73vv70A77-9EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy77-9CBRC77-977-977-977-9CSMzUu-_vRVicu-_vQoWJDTvv70l77-9FxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXrvv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv70AQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU77-977-9AEMBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFO-_ve-_vQAEAALvv73vv70ADAMBAAIRAxEAPwDvv73vv71f77-9F--_vRvvv73vv70l77-977-977-9Pwhq77-9cNuZ77-9aO-_vSDvv73vv73YtO-_vVhGEe-_ve-_vR5A77-977-9AAdx77-977-977-977-977-947eFPC4vZO-_vdabUe-_vVZ0Gu-_vVwI77-9Ru-_vVQqLe-_vXLvv71OZBhXDu-_vRdqbe-_vRbvv73vv73vv70X77-977-9TxTvv73vv73vv73ane-_ve-_ve-_vVrvv73vv70r77-977-9E--_ve-_vQvvv71V77-9A--_vVAXAO-_ve-_vdW7P--_vXw977-977-977-9EO-_ve-_vTHvv70d77-9e--_ve-_ve-_ve-_vUlU77-977-977-9OO-_vXIA77-977-977-977-9be-_ve-_ve-_ve-_vUVu77-9b--_ve-_ve-_ve-_vTUI77-9OO-_ve-_ve-_vX3vv73vv73vv73vv73vv71K1q4tIu-_vVfvv71777-977-977-9M--_vQ3vv73vv70R77-9Ge-_ve-_ve-_ve-_ve-_vW0IP--_ve-_ve-_ve-_ve-_ve-_vX_vv73vv73vv73vv71d77-9dV_vv73vv71Nc1jvv700QO-_vRpqUwDvv704AA3vv70rO--_vV9X77-9AO-_ve-_ve-_ve-_vQDvv70577-9AO-_ve-_ve-_ve-_vVR_b--_vQAl77-9AO-_vTbvv73vv71_X3Hvv73vv70

3. Buffer.from(data).toString("base64")

Even though this is a Node.js API and doesn't work in my browser, I gave it a try wrapping it in if (import.meta.env.SSR), but I get the same 77+977+977...Hvv73vv70= output from above.

So what am I missing here? How do I get the correct Base64 output? I tried taking the "incorrect" output I got and correctly prefixing it with data:image/jpeg;base64,, but not surprisingly the browser doesn't render it. What do I need to do to get the same "correct" output which I got when running the image through https://www.base64-image.de?

Share Improve this question asked Feb 1, 2023 at 22:03 Aaron BeaudoinAaron Beaudoin 5871 gold badge8 silver badges19 bronze badges 2
  • Does this answer your question? stackoverflow./questions/6150289/… – Peter Thoeny Commented Feb 2, 2023 at 2:08
  • Not really. It doesn't explain why the solutions I tried above didn't work like I expected them to, and the solutions are all specific to either browser-side JS or Node.js. I need something isomorphic. – Aaron Beaudoin Commented Feb 2, 2023 at 15:54
Add a ment  | 

2 Answers 2

Reset to default 10

Don't do this at rutime. Create a loader in your vite.config.ts

const base64Loader: Plugin = {
  name: "base64-loader",
  transform(_: any, id: string) {
    const [path, query] = id.split("?");
    if (query != "base64") return null;

    const data = fs.readFileSync(path);
    const base64 = data.toString("base64");

    return `export default '${base64}';`;
  },
};

Add it as a plugin

plugins: [ base64Loader, etc...],

Then import the images as base64.

import data from "whatever.jpg?base64"

As an addition to @rvllzzr's answer, you might want to add the following types:

declare global {
    declare module "*?base64" {
        const value: string;
        export = value;
    };
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1743711375a216116.html

最新回复(0)