Как закодировать/декодировать строку в Base64 на JavaScript?
У меня есть PHP-скрипт, который может кодировать PNG-изображение в строку Base64.
Теперь я хочу сделать то же самое на JavaScript. Я знаю, как открывать файлы, но не уверен, как выполнить кодирование. У меня нет опыта работы с двоичными данными.
5 ответ(ов)
Если вы используете Node.js, вы можете сделать это следующим образом:
let a = Buffer.from('JavaScript').toString('base64');
console.log(a);
let b = Buffer.from(a, 'base64').toString();
console.log(b);
В этом коде мы сначала создаем строку в формате Base64 из текста 'JavaScript' с помощью Buffer.from()
и метода toString('base64')
. Затем мы декодируем ее обратно в исходный текст, используя Buffer.from(a, 'base64').toString()
. Результаты выводятся в консоль.
В обеих реализациях функции _utf8_decode
есть несколько ошибок. Переменные c1
и c2
объявлены как глобальные из-за неправильного использования оператора var
, а c3
вообще не инициализирован и не объявлен.
Хотя код работает, такие переменные могут перезаписать существующие переменные с такими же именами вне этой функции.
Вот исправленная версия, которая этого не делает:
// приватный метод для декодирования UTF-8
_utf8_decode: function (utftext) {
var string = "";
var i = 0;
var c = 0;
var c1 = 0;
var 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;
}
Такой код избегает конфликтов с глобальной областью видимости и работает корректно.
Для современных браузеров вы можете использовать следующие функции для кодирования и декодирования в формат Base64:
const base64 = {
decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
encode: b => btoa(String.fromCharCode(...new Uint8Array(b))),
decodeToString: s => new TextDecoder().decode(base64.decode(s)),
encodeString: s => base64.encode(new TextEncoder().encode(s)),
};
Для Node.js выполните следующие действия, чтобы закодировать строку, Buffer или Uint8Array в строку и декодировать из строки, Buffer или Uint8Array в Buffer:
const base64 = {
decode: s => Buffer.from(s, 'base64'),
encode: b => Buffer.from(b).toString('base64')
};
Эти примеры обеспечивают простое и удобное кодирование и декодирование данных в формате Base64 как в браузерах, так и в среде Node.js.
Этот вопрос и его ответы указали мне правильное направление. Особенно с учётом того, что в наше время всё является Unicode, функции atob и btoa не могут быть использованы "в чистом виде".
Прямо от 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"
Эти функции работают на удивление быстро по сравнению с "сырым" декодированием Base64 с использованием пользовательской функции JavaScript, так как btoa и atob выполняются вне интерпретатора.
Если вы можете игнорировать старый Internet Explorer и старые мобильные телефоны (например, iPhone 3?), то это должно быть хорошим решением.
Вы можете написать код, который позволяет кодировать и декодировать строки, используя методы base64
и utf8
. В вашем случае вы хотите реализовать эти методы в модульном формате, что обеспечит совместимость между платформами и браузерами, а также реальную защиту области видимости переменных.
Вот пример, как вы можете структурировать свой код:
const base64 = (() => {
const hasBtoa = typeof btoa === 'function';
const hasAtob = typeof atob === 'function';
function encode(input) {
if (hasBtoa) {
return btoa(unescape(encodeURIComponent(input)));
}
// Реализуйте свою логику кодирования в случае отсутствия btoa
}
function decode(input) {
if (hasAtob) {
return decodeURIComponent(escape(atob(input)));
}
// Реализуйте свою логику декодирования в случае отсутствия atob
}
return {
encode,
decode
};
})();
const utf8 = (() => {
function encode(input) {
return unescape(encodeURIComponent(input));
}
function decode(input) {
return decodeURIComponent(escape(input));
}
return {
encode,
decode
};
})();
Использование:
const encodedBase64 = base64.encode('Hello, World!');
const decodedBase64 = base64.decode(encodedBase64);
const encodedUtf8 = utf8.encode('Привет, мир!');
const decodedUtf8 = utf8.decode(encodedUtf8);
Этот модульный подход позволяет использовать стандартные функции coder/decoder btoa
и atob
, если они доступны, что делает код быстрее при работе с base64. Если они не доступны, вы можете добавить свою реализацию кодирования и декодирования, чтобы обеспечить совместимость в других окружениях.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"