我有一个 PHP 脚本,可以将 PNG 图像编码为 Base64 字符串。
我想用 JavaScript 做同样的事情。我知道如何打开文件,但我不确定如何进行编码。我不习惯使用二进制数据。
您可以使用 btoa()
和 atob()
与 base64 编码相互转换。
关于这些函数接受/返回什么的评论似乎有些混乱,所以……
btoa() 接受一个“字符串”,其中每个字符代表一个 8 位字节——如果您传递的字符串包含不能用 8 位表示的字符,它可能会中断。如果您实际上将字符串视为字节数组,这不是问题,但如果您尝试做其他事情,那么您必须先对其进行编码。
atob() 返回一个“字符串”,其中每个字符代表一个 8 位字节——也就是说,它的值将介于 0 和 0xff 之间。这并不意味着它是 ASCII ——大概如果你使用这个函数,你希望使用二进制数据而不是文本。
也可以看看:
如何使用 Javascript 和 XMLHttpRequest 加载二进制图像数据?
这里的大多数评论都已过时。您可以同时使用 btoa()
和 atob()
,除非您支持真正过时的浏览器。
在这里检查:
https://caniuse.com/?search=atob
https://caniuse.com/?search=btoa
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
此外,搜索 "JavaScript base64 encoding" 会出现许多其他选项,以上是第一个选项。
string = string.replace(/\r\n/g,"\n");
语句。
string = string.replace(/\r\n/g,"\n");
,哈哈。这就像“哦,让我们对这个字符串进行编码,但首先,我们为什么不完全没有充分理由地随机标准化所有换行符”。在任何情况下都应该从课堂上删除它。
互联网浏览器 10+
// Define the string
var string = 'Hello World!';
// Encode the String
var encodedString = btoa(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
// Decode the String
var decodedString = atob(encodedString);
console.log(decodedString); // Outputs: "Hello World!"
跨浏览器
// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
// Define the string
var string = 'Hello World!';
// Encode the String
var encodedString = Base64.encode(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
// Decode the String
var decodedString = Base64.decode(encodedString);
console.log(decodedString); // Outputs: "Hello World!"
使用 Node.js
以下是在 Node.js 中将普通文本编码为 base64 的方法:
//Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter.
// The default is "utf8". Possible encoding types are "ascii", "utf8", "ucs2", "base64", "binary", and "hex"
var b = Buffer.from('JavaScript');
// If we don't use toString(), JavaScript assumes we want to convert the object to utf8.
// We can make it convert to other formats by passing the encoding type to toString().
var s = b.toString('base64');
以下是解码 base64 编码字符串的方法:
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
使用 Dojo.js
使用 dojox.encoding.base64 对字节数组进行编码:
var str = dojox.encoding.base64.encode(myByteArray);
要解码 Base64 编码的字符串:
var bytes = dojox.encoding.base64.decode(str)
Bower 安装 angular-base64
<script src="bower_components/angular-base64/angular-base64.js"></script>
angular
.module('myApp', ['base64'])
.controller('myController', [
'$base64', '$scope',
function($base64, $scope) {
$scope.encoded = $base64.encode('a string');
$scope.decoded = $base64.decode('YSBzdHJpbmc=');
}]);
new Buffer()
已弃用,请改用 Buffer.from()
Sunny's code 很好,只是它在 Internet Explorer 7 中因引用“this”而中断。通过用“Base64”替换这些引用来修复它:
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = Base64._keyStr.indexOf(input.charAt(i++));
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
enc4 = Base64._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
您可以使用 btoa
(到 Base64)和 atob
(从 Base64)。
对于 Internet Explorer 9 及更低版本,请尝试 jquery-base64 插件:
$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
base64.encode(...)
和 base64.decode(...)
...当它具有零 jQuery 特定功能时将其附加到 jQuery 绝对没有意义...
从已接受答案下方的评论(由 SET 和 Stefan Steiger 撰写),这里是如何在不需要库的情况下将字符串编码/解码到/从 Base64 的快速摘要。
str = "The quick brown fox jumps over the lazy dog";
b64 = btoa(unescape(encodeURIComponent(str)));
str = decodeURIComponent(escape(window.atob(b64)));
纯 JavaScript 演示
常量输入 = document.getElementsByTagName('input')[0];常量 btnConv = document.getElementById('btnConv');常量 btnDeConv = document.getElementById('btnDeConv'); input.value = "敏捷的棕狐跳过懒狗"; btnConv.addEventListener('click', () => { const txt = input.value; const b64 = btoa(unescape(encodeURIComponent(txt))); input.value = b64; btnDeConv.style.display = 'block'; btnConv.style.display = '无'; }); btnDeConv.addEventListener('click', () => { var b64 = input.value; var txt = decodeURIComponent(escape(window.atob(b64))); input.value = txt; btnConv.style.display = 'block '; btnDeConv.style.display = '无'; }); input{width:500px;} #btnDeConv{display:none;}
.
jQuery Demo(使用 jQuery 库进行显示,但不用于编码/解码)
str = "敏捷的棕色狐狸跳过懒惰的狗"; $('输入').val(str); $('#btnConv').click(function(){ var txt = $('input').val(); var b64 = btoa(unescape(encodeURIComponent(txt))); $('input').val (b64); $('#btnDeConv').show(); }); $('#btnDeConv').click(function(){ var b64 = $('input').val(); var txt = decodeURIComponent(escape(window.atob(b64))); $('input') .val(txt); }); #btnDeConv{display:none;}
Buffer.from(b64data, 'base64').toString();
unescape
和 escape
在这个解决方案中做了什么吗?
_utf8_decode
的两种实现中都有几个错误。 c1
和 c2
由于 var
语句的错误使用而被分配为全局变量,并且 c3
根本没有被初始化或声明。
它可以工作,但是这些变量将覆盖此函数之外任何具有相同名称的现有变量。
这是一个不会这样做的版本:
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = 0, c1 = 0, c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
}
else {
c1 = utftext.charCodeAt(i+1);
c2 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
return string;
}
这个问题及其答案为我指明了正确的方向。尤其是 Unicode,不能使用 atob 和 btoa “香草”,而现在一切都是 Unicode...
直接来自 Mozilla,为此提供了两个不错的功能。使用 Unicode 和 HTML 标签测试:
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64EncodeUnicode('\n'); // "Cg=="
function b64DecodeUnicode(str) {
return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
b64DecodeUnicode('Cg=='); // "\n"
与使用自定义 JavaScript 函数的原始 Base64 解码相比,这些函数的执行速度快如闪电,因为 btoa 和 atob 在解释器之外执行。
如果您可以忽略旧 Internet Explorer 和旧手机(如 iPhone 3?),这应该是一个很好的解决方案。
对于较新的浏览器将 Uint8Array 编码为字符串,并将字符串解码为 Uint8Array。
const base64 = {
decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
};
对于 Node.js,您可以使用以下代码将字符串、缓冲区或 Uint8Array 编码为字符串,并将字符串、缓冲区或 Uint8Array 解码为缓冲区。
const base64 = {
decode: s => Buffer.from(s, 'base64'),
encode: b => Buffer.from(b).toString('base64')
};
如果你使用 Node.js,你可以这样做:
let a = Buffer.from('JavaScript').toString('base64');
console.log(a);
let b = Buffer.from(a, 'base64').toString();
console.log(b);
基本上我只是稍微清理了 the original code,所以 JSLint 并没有太多抱怨,而且我在评论中将标记为私有的方法设置为私有。我还添加了我自己项目中需要的两个方法,即 decodeToHex
和 encodeFromHex
。
编码:
var Base64 = (function() {
"use strict";
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var _utf8_encode = function (string) {
var utftext = "", c, n;
string = string.replace(/\r\n/g,"\n");
for (n = 0; n < string.length; n++) {
c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
var _utf8_decode = function (utftext) {
var string = "", i = 0, c = 0, c1 = 0, c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
} else {
c1 = utftext.charCodeAt(i+1);
c2 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
return string;
};
var _hexEncode = function(input) {
var output = '', i;
for(i = 0; i < input.length; i++) {
output += input.charCodeAt(i).toString(16);
}
return output;
};
var _hexDecode = function(input) {
var output = '', i;
if(input.length % 2 > 0) {
input = '0' + input;
}
for(i = 0; i < input.length; i = i + 2) {
output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16));
}
return output;
};
var encode = function (input) {
var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output += _keyStr.charAt(enc1);
output += _keyStr.charAt(enc2);
output += _keyStr.charAt(enc3);
output += _keyStr.charAt(enc4);
}
return output;
};
var decode = function (input) {
var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output += String.fromCharCode(chr1);
if (enc3 !== 64) {
output += String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output += String.fromCharCode(chr3);
}
}
return _utf8_decode(output);
};
var decodeToHex = function(input) {
return _hexEncode(decode(input));
};
var encodeFromHex = function(input) {
return encode(_hexDecode(input));
};
return {
'encode': encode,
'decode': decode,
'decodeToHex': decodeToHex,
'encodeFromHex': encodeFromHex
};
}());
请注意,这不适用于原始 Unicode 字符串!请参阅 Unicode 部分 here。
编码语法
var encodedData = window.btoa(stringToEncode);
解码语法
var decodedData = window.atob(encodedData);
我已经手动将这些编码和解码方法重写为除了十六进制之外的模块化格式,以实现跨平台/浏览器兼容性以及真正的私有范围,如果由于速度而存在,则使用 btoa
和 atob
而不是使用自己的编码:
https://gist.github.com/Nijikokun/5192472
用法:
base64.encode(/* String */);
base64.decode(/* String */);
utf8.encode(/* String */);
utf8.decode(/* String */);
要使 Base64 编码的字符串 URL 友好,在 JavaScript 中您可以执行以下操作:
// if this is your Base64 encoded string
var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA==';
// make URL friendly:
str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
// reverse to original encoding
str = (str + '===').slice(0, str.length + (str.length % 4));
str = str.replace(/-/g, '+').replace(/_/g, '/');
另请参阅此小提琴:http://jsfiddle.net/magikMaker/7bjaT/
encodeURIComponent
很可能会导致开发人员花费更少的精力而获得更好的结果。
如果需要对 HTML 图像对象进行编码,可以编写一个简单的函数,例如:
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
// escape data:image prefix
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
// or just return dataURL
// return dataURL
}
通过 id 获取图像的 Base64 编码:
function getBase64ImageById(id){
return getBase64Image(document.getElementById(id));
}
更多是here。
您可以使用 window.btoa
和 window.atob
...
const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
const decoded = window.atob(encoded); // decode the string
可能使用 MDN 的方式可以让你的工作做得最好......也接受 Unicode...... 使用这两个简单的功能:
// UCS-2 string to Base64 encoded ASCII
function utoa(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}
// Base64 encoded ASCII to UCS-2 string
function atou(str) {
return decodeURIComponent(escape(window.atob(str)));
}
// Usage:
utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
我的一个项目需要将 UTF-8 字符串编码为 Base64。在转换为 UTF-8 时,这里的大多数答案似乎都无法正确处理 UTF-16 代理对,因此,为了完整起见,我将发布我的解决方案:
function strToUTF8Base64(str) {
function decodeSurrogatePair(hi, lo) {
var resultChar = 0x010000;
resultChar += lo - 0xDC00;
resultChar += (hi - 0xD800) << 10;
return resultChar;
}
var bytes = [0, 0, 0];
var byteIndex = 0;
var result = [];
function output(s) {
result.push(s);
}
function emitBase64() {
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz' +
'0123456789+/';
function toDigit(value) {
return digits[value];
}
// --Byte 0-- --Byte 1-- --Byte 2--
// 1111 1122 2222 3333 3344 4444
var d1 = toDigit(bytes[0] >> 2);
var d2 = toDigit(
((bytes[0] & 0x03) << 4) |
(bytes[1] >> 4));
var d3 = toDigit(
((bytes[1] & 0x0F) << 2) |
(bytes[2] >> 6));
var d4 = toDigit(
bytes[2] & 0x3F);
if (byteIndex === 1) {
output(d1 + d2 + '==');
}
else if (byteIndex === 2) {
output(d1 + d2 + d3 + '=');
}
else {
output(d1 + d2 + d3 + d4);
}
}
function emit(chr) {
bytes[byteIndex++] = chr;
if (byteIndex == 3) {
emitBase64();
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
byteIndex = 0;
}
}
function emitLast() {
if (byteIndex > 0) {
emitBase64();
}
}
// Converts the string to UTF8:
var i, chr;
var hi, lo;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
// Test and decode surrogate pairs in the string
if (chr >= 0xD800 && chr <= 0xDBFF) {
hi = chr;
lo = str.charCodeAt(i + 1);
if (lo >= 0xDC00 && lo <= 0xDFFF) {
chr = decodeSurrogatePair(hi, lo);
i++;
}
}
// Encode the character as UTF-8.
if (chr < 0x80) {
emit(chr);
}
else if (chr < 0x0800) {
emit((chr >> 6) | 0xC0);
emit(((chr >> 0) & 0x3F) | 0x80);
}
else if (chr < 0x10000) {
emit((chr >> 12) | 0xE0);
emit(((chr >> 6) & 0x3F) | 0x80);
emit(((chr >> 0) & 0x3F) | 0x80);
}
else if (chr < 0x110000) {
emit((chr >> 18) | 0xF0);
emit(((chr >> 12) & 0x3F) | 0x80);
emit(((chr >> 6) & 0x3F) | 0x80);
emit(((chr >> 0) & 0x3F) | 0x80);
}
}
emitLast();
return result.join('');
}
请注意,代码未经过彻底测试。我测试了一些输入,包括 strToUTF8Base64('衠衢蠩蠨')
之类的内容,并与在线编码工具 (https://www.base64encode.org/) 的输出进行了比较。
这是 window.atob
+ window.btoa
的缩小 polyfill:
(function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function() {factory(root);});
} else factory(root);
// node.js has always supported base64 conversions, while browsers that support
// web workers support base64 too, but you may never know.
})(typeof exports !== "undefined" ? exports : this, function(root) {
if (root.atob) {
// Some browsers' implementation of atob doesn't support whitespaces
// in the encoded string (notably, IE). This wraps the native atob
// in a function that strips the whitespaces.
// The original function can be retrieved in atob.original
try {
root.atob(" ");
} catch(e) {
root.atob = (function(atob) {
var func = function(string) {
return atob(String(string).replace(/[\t\n\f\r ]+/g, ""));
};
func.original = atob;
return func;
})(root.atob);
}
return;
}
// 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}=?)?$/;
root.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;
};
root.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);
}
return result;
};
});
https://github.com/MaxArt2501/base64-js/blob/master/base64.js 的完整版
这是@user850789 的AngularJS Factory 版本:
'use strict';
var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []);
ProjectNameBase64Factory.factory('Base64', function () {
var Base64 = {
// private property
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode: function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode: function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = Base64._keyStr.indexOf(input.charAt(i++));
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
enc4 = Base64._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode: function (string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode: function (utftext) {
var string = "";
var i = 0;
var c = 0, c2 = 0, c3 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
};
return Base64;
});
以下是 atob()
和 btoa()
JavaScript 内置函数的 LIVE DEMO:
<!DOCTYPE html>
<html>
<head>
<style>
textarea{
width:30%;
height:100px;
}
</style>
<script>
// encode string to base64
function encode()
{
var txt = document.getElementById("txt1").value;
var result = btoa(txt);
document.getElementById("txt2").value = result;
}
// decode base64 back to original string
function decode()
{
var txt = document.getElementById("txt3").value;
var result = atob(txt);
document.getElementById("txt4").value = result;
}
</script>
</head>
<body>
<div>
<textarea id="txt1">Some text to decode
</textarea>
</div>
<div>
<input type="button" id="btnencode" value="Encode" onClick="encode()"/>
</div>
<div>
<textarea id="txt2">
</textarea>
</div>
<br/>
<div>
<textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
</textarea>
</div>
<div>
<input type="button" id="btndecode" value="Decode" onClick="decode()"/>
</div>
<div>
<textarea id="txt4">
</textarea>
</div>
</body>
</html>
对于我的项目,我仍然需要支持 IE7 并使用大量输入进行编码。
根据 Joe Dyndale 提出的代码和 Marius 在评论中的建议,可以通过使用数组而不是字符串构造结果来提高 IE7 的性能。
这是编码的示例:
var encode = function (input) {
var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output.push(_keyStr.charAt(enc1));
output.push(_keyStr.charAt(enc2));
output.push(_keyStr.charAt(enc3));
output.push(_keyStr.charAt(enc4));
}
return output.join("");
};
好吧,如果您使用的是 Dojo。它为我们提供了直接编码或解码为 Base64 的方法。
尝试这个:
使用 dojox.encoding.base64 对字节数组进行编码:
var str = dojox.encoding.base64.encode(myByteArray);
要解码 Base64 编码的字符串:
var bytes = dojox.encoding.base64.decode(str);
虽然需要做更多工作,但如果您想要一个高性能的原生解决方案,您可以使用一些 HTML5 函数。
如果您可以将数据放入 Blob
,那么您可以使用 FileReader.readAsDataURL() 函数来获取 data://
URL 并切掉它的前面以获取 Base64 数据。
但是,您可能需要进行进一步处理才能对数据进行 urldecode,因为我不确定 data://
URL 是否对 +
字符进行了转义,但这应该很简单。
使用 js-base64 库作为
btoa() 不适用于表情符号
var str = "我很有趣😂"; console.log("原始字符串:", str); var encodedStr = Base64.encode(str) console.log("编码字符串:", encodedStr); var decodedStr = Base64.decode(encodedStr) console.log("解码字符串:", decodedStr);
当我使用
btoa("☸☹☺☻☼☾☿"))
我得到:
错误 InvalidCharacterError:要编码的字符串包含 Latin1 范围之外的字符。
我发现文档 Unicode strings 提供了如下解决方案。
函数 toBinary(string) { const codeUnits = new Uint16Array(string.length); for (let i = 0; i < codeUnits.length; i++) { codeUnits[i] = string.charCodeAt(i); } return String.fromCharCode(...new Uint8Array(codeUnits.buffer)); } function fromBinary(binary) { const bytes = new Uint8Array(binary.length); for (let i = 0; i < bytes.length; i++) { bytes[i] = binary.charCodeAt(i); } return String.fromCharCode(...new Uint16Array(bytes.buffer)); } const myString = "☸☹☺☻☼☾☿" // console.log(btoa(myString)) // 错误 InvalidCharacterError:要编码的字符串包含 Latin1 范围之外的字符。 const 转换 = toBinary(myString) const 编码 = btoa(converted) console.log(encoded) const decoded = atob(encoded) const original = fromBinary(decoded) console.log(original);
2022 年弃用警告更新
我在我的 vscode 上看到了弃用警告
This function is only provided for compatibility with legacy web platform APIs and should never be used in new code,
because they use strings to represent binary data and predate the introduction of typed arrays in JavaScript.
For code running using Node.js APIs,
converting between base64-encoded strings and binary data should be performed using Buffer.from(str, 'base64') andbuf.toString('base64').
在搜索了更多之后,我发现这个问题说它没有被弃用
https://github.com/microsoft/TypeScript/issues/45566
所以解决web JS上的弃用警告,使用window.btoa
,警告就会消失。
没有 btoa 中间步骤的 JavaScript(没有库)
在你写的关于字符串转换的问题标题中,但在你谈论二进制数据(图片)的问题中,这是一个从 PNG 图片二进制数据开始进行正确转换的函数(细节和反转转换是 here)。
https://i.stack.imgur.com/g2aN7.png
函数 bytesArrToBase64(arr) { const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 字母 const bin = n => n.toString(2).padStart(8,0); // 将 num 转换为 8 位二进制字符串 const l = arr.length let result = ''; for(让 i=0; i<=(l-1)/3; i++) { 让 c1 = i*3+1>=l; // 当 "=" 结束时的情况 let c2 = i*3+2>=l; // 当 "=" 结束时的情况 let chunk = bin(arr[3*i]) + bin(c1? 0:arr[3*i+1]) + bin(c2? 0:arr[3*i +2]);让 r = chunk.match(/.{1,6}/g).map((x,j)=> j==3&&c2 ? '=' :(j==2&&c1 ? '=':abc[+( '0b'+x)]));结果 += r.join(''); } 返回结果; } // TEST const pic = [ // PNG 二进制数据 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x , 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0xae 0x, 0x, 0x, 0x, 0x, 0x, , 0x1c, 0xe9, 0x00, 0x00, 0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78 , 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78 , 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b , 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64 , 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3 d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 9, 03x 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0 x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x0a, 020, 0x0a, 020, 020, 0x 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x00, 0xf9, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0x95, 0x93, 0x3d, 0x0a, 0x02, 0x41, 0x0c, 0x85, 0xb3, 0xb2, 0x85, 0xb7, 0x10, 0x6c, 0x04, 0x1b, 0x0b, 0x4b, 0x6f, 0xe2, 0x76, 0x1e, 0xc1, 0xc2, 0x56, 0x6c, 0x2d, 0xbc, 0x85, 0xde, 0xc4, 0xd2, 0x56, 0xb0, 0x11, 0xbc, 0x85, 0x85, 0xa0, 0xfb, 0x46, 0xbf, 0xd9, 0x30, 0x33, 0x88, 0x06, 0x76, 0x93, 0x79, 0x93, 0xf7, 0x92, 0xf9, 0xab, 0xcc, 0xec, 0xd9, 0x7e, 0xd9, 0x7e, 03x 0x8e, 0xf9, 0x75, 0x8c, 0x92, 0xe0, 0x34, 0xe8, 0x27, 0x88, 0xd9, 0xf4, 0x76, 0xcf, 0xb0, 0xaa, 0x45, 0xb2, 0x0e, 0x4a, 0xe4, 0x94, 0x39, 0x59, 0x0c, 0x03, 0x54, 0x14, 0x58, 0xce, 0xbb, 0xea, 0xdb, 0xd1, 0x3b, 0x71, 0x75, 0xb9, 0xa, 0xb9, 0xa, 0x36, 0x3f, 0xdf, 0x4b, 0x95, 0x35, 0x09, 0x09, 0xef, 0x73, 0xfc, 0xfa, 0x85, 0x67, 0x02, 0x3e, 0x59, 0x55, 0x31, 0x89, 0x31, 0x86, 0x31, 0x86, 0x31, 0x86 0x04, 0xda, 0x23, 0x01, 0x01, 0xc8, 0x8c, 0xe5, 0x77, 0x87, 0xbb, 0x65, 0x02, 0x24, 0xa4, 0xad, 0x82, 0xcb, 0x4b, 0x4c, 0x64, 0x050 0x40, 0x3f, 0xbf, 0xe6, 0x68, 0xb6, 0x9f, 0x75, 0x08, 0x63, 0xc8, 0x9a, 0x09, 0x02, 0x25, 0x32, 0x34, 0x48, 0x7e, 0x6, 0, 0f, 5x, 0xa 0xd2, 0x1a, 0x3d, 0x89, 0x38, 0xf5, 0xf1, 0x14, 0xb4, 0x69, 0x6a, 0x4d, 0x15, 0xf5, 0xc9, 0xf0, 0x5c, 0x1a, 0x61, 0x8a, 0x75, 0xd1, 0xe8, 0x3a, 0x2c, 0x41, 0x5d, 0x70, 0x41, 0x20, 0x29, 0xf9, 0x9b, 0xb1, 0x37, 0xc5, 0x4d, 0xfc, 0x45, 0x84, 0x7d, 0x08, 0x8f, 0x89, 0x76, 0x54, 0xf1, 0x1b, 0x19, 0x92, 0xef, 0x2c, 0xbe, 0x46, 0x8e, 0xa6, 0x49, 0x5e, 0x61, 0x89, 0xe4, 0x05, 0x5e, 0x4e, 0xa4, 0x5c, 0x1 0、0x6e、0x9f、0xfc、0x5b、0x00、0x00、0x00、0x00、0x49、0x45、0x4e、0x44、0xae、0x42、0x60、0x82];让 b64pic = bytesArrToBase64(pic); myPic.src = "数据:图像/png;base64,"+b64pic; msg.innerHTML = "Base64 编码图片数据:
" + b64pic; img {缩放:10;图像渲染:像素化; } #msg { word-break: break-all; }
这是编码为 base64url 的辅助函数:
base64url (s) {
var to64url = btao(s);
// Replace non-url compatible chars with base64url standard chars and remove leading =
return to64url.replace(/\+/g, '_').replace(/\//g, '-').replace(/=+$/g, '');
}
btoa
不是 btao
您可以在浏览器中使用 btoa()/atob(),但需要进行一些改进,如此处 https://base64tool.com/uncaught-domexception-btoa-on-window/ 和此处 https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa 所述,以支持 UTF 字符串!
btoa(unescape(encodeURIComponent(str))))
b to a
和a to b
,b 代表二进制,a 代表 ASCII