Base64 is a similar set of binary-to-text encoding rules that enable binary data to be represented in ASCII string format after being interpreted to the Radix 64 representation. The word Base64 comes from a MIME data transmission encoding.
The browser
Modern browsers natively support base64 codec, which can be used in both the console and JS worker. It provides two methods: ATob () btoa() for decoding and encoding, respectively.
btoa()
Creates a base-64 encoded ASCII String from a String object, where each character in the String is treated as a binary data byte.
Because this function treats each character as a byte of binary data, regardless of the actual number of bytes that make up the character, an InvalidCharacterError exception is raised if any character’s code point is outside the range 0x00 to 0xFF. See the Unicode_ string for an example that demonstrates how to encode a string containing characters with code points outside the range 0x00 to 0xFF.
Therefore, this function can only encode ASCLL strings in base64 format, and will report an error for strings other than ASCLL
The error message contains characters that are not encoded in latin1. These characters cannot be encoded.
Latin1: Latin-1 stands for ISO-8859-1. This character encoding only supports Unicode characters from U+0000 to U+00FF. Each character is encoded using a single byte. Characters outside this range are truncated and mapped to characters within this range.
The solution is to escape the non-ASCLL characters in the string and then encode them
// unicode to base64
function utoa(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}
Copy the code
The code above is derived from the MDN document WindowOrWorkerGlobalScope. Btoa ()
EncodeURIComponent is used to escape non-ASCLL characters in a string into a hexadecimal escape sequence in the format “% ASCII plus characters “, used in URI processing.
The processed string consists entirely of ASCLL characters, which are then converted by unescape() into a hexadecimal escape sequence, and then encoded into base64 by btoa(), but unescape() is not necessary because it is deprecated by the Web standard. The second is that the escaped string can already be encoded by btoA ().
function utoa(str) {
return window.btoa(encodeURIComponent(str));
}
Copy the code
// unicode to base64 by
function utoa(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}
// base64 to unicode
function atou(str) {
return decodeURIComponent(escape(window.atob(str)));
}
Copy the code
atob()
As above, using atob() directly to convert a base64 string encoded from a string that does not consist entirely of ASCLL characters will result in the same error as above.
MDN document WindowOrWorkerGlobalScope. Btoa () method
// base64 to unicode
function atou(str) {
return decodeURIComponent(escape(window.atob(str)));
}
Copy the code
Escape () is not necessary
function atou(str) {
return decodeURIComponent(window.atob(str));
}
Copy the code
Polyfill
Many PC projects need to be compatible with IE9 and below, so we can introduce a ployfill script or a JS file specifically for these browsers.
Github.com/MaxArt2501/…
Another ployfill implementation
Github.com/davidchambe…
// Polyfill from https://github.com/MaxArt2501/base64-js/blob/master/base64.js
(function() {
// base64 character set, plus padding character (=)
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".// Regular expression to check formal correctness of base64 encoded strings
b64re = / ^ (? :[A-Za-z\d+\/]{4})*? (? :[A-Za-z\d+\/]{2}(? : = =)? |[A-Za-z\d+\/]{3}=?) ? $/;
window.btoa = window.btoa || function(string) {
string = String(string);
var bitmap, a, b, c,
result = "",
i = 0,
rest = string.length % 3; // To determine the final padding
for (; i < string.length;) {
if ((a = string.charCodeAt(i++)) > 255 ||
(b = string.charCodeAt(i++)) > 255 ||
(c = string.charCodeAt(i++)) > 255)
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
bitmap = (a << 16) | (b << 8) | c;
result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) +
b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
}
// If there's need of padding, replace the last 'A's with equal signs
return rest ? result.slice(0, rest - 3) + "= = =".substring(rest) : result;
};
window.atob = window.atob || function(string) {
// atob can work with strings with whitespaces, even inside the encoded part,
// but only \t, \n, \f, \r and ' ', which can be stripped.
string = String(string).replace(/[\t\n\f\r ]+/g."");
if(! b64re.test(string))throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
// Adding the padding if missing, for semplicity
string += "= =".slice(2 - (string.length & 3));
var bitmap, result = "",
r1, r2, i = 0;
for (; i < string.length;) {
bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 |
(r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) :
r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) :
String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
}
returnresult; }; }) ()Copy the code
Convert typed arrays to Base64
Sometimes the back end passes us a binary stream of file resources that we need to use a typed array to store and read.
Arraybuffers, called typed arrays, were created to solve a problem: manipulating binary data.
Binary data consisting only of zeros and ones is often very large. Thousands of bytes are not uncommon. Traditional arrays are very inefficient to handle binary data.
Let’s now initialize a buffer instance with new ArrayBuffer(10) and see what we get.
let buffer = new ArrayBuffer(10);
console.log(buffer);
ArrayBuffer(10) {}
[[Int8Array]] :Int8Array(10) [0.0.0.0.0.0.0.0.0.0]
[[Int16Array]] :Int16Array(5) [0.0.0.0.0]
[[Uint8Array]] :Uint8Array(10) [0.0.0.0.0.0.0.0.0.0]
byteLength: 10
__proto__: ArrayBuffer
Copy the code
As you can see, there are several views in the ArrayBuffer. Int8Array represents an array of 8-bit signed integers, Int16Array represents an array of 16-bit signed integers, and Uint8Array represents an array of 8-bit unsigned integers.
Of course, if we want to fetch Int8Array, for example, we can’t fetch it directly from buffer.int8Array. This is because the ArrayBuffer cannot be read or written directly by subscript, so we need to construct an array instance of the related type.
const myUint8Array = new Uint8Array(buffer)
Copy the code
Once you have the array value, how do you convert it to Base64? Simply use the string.fromCharCode function, which takes a sequence of code units as an argument and outputs a plain String. And the typed array that we just got is exactly where the code units are.
const myStr = String.fromCharCode(... myUint8Array)Copy the code
Now that the values in the type array are all converted to strings, we encode them into base64 strings using btoa()
node
Although the Node environment does not provide a special method for codec base64, we can easily do so using buffer.toString(), which is not only useful for processing strings, but also for processing files.
Processing strings
function stringToBase64(str){
let base64Str = Buffer.from(str).toString('base64')
return base64Str;
}
function base64ToString(base64Str){
let str = Buffer.from(base64Str,'base64').toString()
return str
}
Copy the code
Handle file
Take a chestnut
Base64 codec an image
/ / code
const fs = require('fs')
const fileToBase64 = fs.readFileSync('./img.png')
console.log(fileToBase64.toString('base64'))
/ / outputiVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAgAElEQVR4Xuy9CZQdZ3Uu+tVcdeah5251t8bWZEuyJGxjecJDGHMJYEISwiPAu7DyXt66YSUv yc3wlEByIXkk910ePCC5gSQ3IYlJwg0EG4ONsS3Pkm1Jlq1Z6kE9nXmqU/Nbe1cdWZiEaAqms+p4tVtSV9X5z66/vt7Dt78tIH7FFogtEFtghVhAWCHrjJcZ WyC2QGwBxIAVb4LYArEFVowFYsBaMbcqXmhsgdgCMWDFeyC2QGyBFWOBGLBWzK2KFxpbILZADFjxHogtEFtgxVggBqwVc6vihcYWiC0QA1a8B2ILxBZYMRaI AWvF3Kp4obEFYgvEgBXvgdgCsQVWjAViwFoxtypeaGyB2AIxYMV7ILZAbIEVY4EYsFbMrYoXGlsgtkAMWPEeiC0QW2DFWCAGrBVzq+KFxhaILRADVrwHYgvE FlgxFogBa8XcqnihsQViC8SAFe.../ / decoding
const base64Tofile = Buffer.from(fileToBase64.toString('base64'),'base64')
// Output img2.png
fs.writeFileSync('img2.png', base64Tofile);
Copy the code
To be recognized by the browser, the encoded file must be prefixed according to its MIME type, such as PNG :data:image/ PNG; Base64,, TXT text :data:text/plain; base64,
Js – base64 library
Github.com/dankogai/js…
See the Github documentation for details, and it’s easy to use