[コード] 6分で読める

[コード] JavaScript での Base64

モダンブラウザAPIを使ったBase64エンコードとデコードの実用的なJavaScript例。

2025年1月 | development

// 基本的なエンコード & デコード

JavaScriptはBase64操作のための組み込み関数を提供しています。btoa()とatob()関数が基本的なエンコードとデコードを処理します:

これらの関数はASCIIテキストでは良く機能しますが、Unicode文字には特別な処理が必要です。

// 基本的なBase64エンコード
const text = 'こんにちは世界';
const encoded = btoa(text);
console.log(encoded); // 44GT44KT44Gr44Gh44Gv5LiW55WM

// 基本的なBase64デコード
const decoded = atob(encoded);
console.log(decoded); // こんにちは世界

// 文字列が有効なBase64かどうかチェック
function isValidBase64(str) {
    try {
        return btoa(atob(str)) === str;
    } catch (err) {
        return false;
    }
}

// Unicode サポート

Unicode文字列の場合、まずUTF-8バイトに変換する必要があります。モダンブラウザはTextEncoderとTextDecoder APIを提供しています:

このアプローチは絵文字、国際文字、その他のUnicodeコンテンツを正しく処理します。

// Unicode安全なBase64エンコード
function encodeBase64(str) {
    const encoder = new TextEncoder();
    const bytes = encoder.encode(str);
    const binary = String.fromCharCode(...bytes);
    return btoa(binary);
}

// Unicode安全なBase64デコード
function decodeBase64(base64) {
    const binary = atob(base64);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
        bytes[i] = binary.charCodeAt(i);
    }
    const decoder = new TextDecoder();
    return decoder.decode(bytes);
}

// 絵文字での例
const emoji = 'こんにちは 👋 世界 🌍';
const encoded = encodeBase64(emoji);
const decoded = decodeBase64(encoded);
console.log(decoded); // こんにちは 👋 世界 🌍

// ファイル処理

ファイルをBase64に変換することは、アップロードやdata URIで一般的です。クライアントサイドでのファイル処理にはFileReader APIを使用してください:

これによりHTMLに直接埋め込まれるか、APIに送信できるdata URIが作成されます。

// ファイルをBase64 data URIに変換
function fileToBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
        reader.readAsDataURL(file);
    });
}

// ファイル入力での使用法
document.getElementById('fileInput').addEventListener('change', async (e) => {
    const file = e.target.files[0];
    if (file) {
        try {
            const base64 = await fileToBase64(file);
            console.log(base64);
            // 結果: data:image/png;base64,iVBORw0KGgoAAAA...
        } catch (error) {
            console.error('エラー:', error);
        }
    }
});

// URL安全なBase64

標準のBase64は+と/文字を使用し、これらはURLエンコードが必要です。URL安全なBase64はこれらを-と_に置換します:

これはトークン、ID、およびURL経由で送信される他のデータに不可欠です。

// URL安全なBase64に変換
function toUrlSafeBase64(base64) {
    return base64
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}

// URL安全なBase64から変換
function fromUrlSafeBase64(urlSafeBase64) {
    let base64 = urlSafeBase64
        .replace(/-/g, '+')
        .replace(/_/g, '/');
    
    // 必要に応じてパディングを追加
    const padding = 4 - (base64.length % 4);
    if (padding !== 4) {
        base64 += '='.repeat(padding);
    }
    
    return base64;
}

// 例
const text = 'URL安全エンコードテスト';
const encoded = btoa(text);
const urlSafe = toUrlSafeBase64(encoded);
console.log(urlSafe); // VVJM5oCJ5YWo44Ko44Oz44Kz44O844OJ44OG44K544OI

// 大容量データのストリーミング

大きなファイルやデータストリームの場合、メモリの問題を避けるためにチャンクごとに処理してください:

このアプローチはブラウザのフリーズを防ぎ、大きなデータセットを効率的に処理します。

// ストリーミングベースのBase64エンコード
class Base64Encoder {
    constructor() {
        this.buffer = '';
    }
    
    encode(chunk) {
        this.buffer += chunk;
        const completeBytes = Math.floor(this.buffer.length / 3) * 3;
        const toEncode = this.buffer.slice(0, completeBytes);
        this.buffer = this.buffer.slice(completeBytes);
        
        return btoa(toEncode);
    }
    
    flush() {
        if (this.buffer.length > 0) {
            const result = btoa(this.buffer);
            this.buffer = '';
            return result;
        }
        return '';
    }
}

// 使用法
const encoder = new Base64Encoder();
let result = '';
result += encoder.encode('最初のチャンク');
result += encoder.encode(' 2番目のチャンク');
result += encoder.flush();
console.log(result);

// エラー処理

Base64操作には常に適切なエラー処理を実装してください:

堅牢なエラー処理はアプリケーションのクラッシュを防ぎ、より良いユーザーエクスペリエンスを提供します。

// エラー処理付きの安全なBase64操作
function safeEncode(input) {
    try {
        if (typeof input !== 'string') {
            throw new Error('入力は文字列である必要があります');
        }
        return btoa(input);
    } catch (error) {
        console.error('エンコードエラー:', error.message);
        return null;
    }
}

function safeDecode(base64) {
    try {
        // Base64フォーマットの検証
        if (!/^[A-Za-z0-9+/]*={0,2}$/.test(base64)) {
            throw new Error('無効なBase64フォーマット');
        }
        return atob(base64);
    } catch (error) {
        console.error('デコードエラー:', error.message);
        return null;
    }
}

// 使用法
const encoded = safeEncode('こんにちは世界');
const decoded = safeDecode(encoded);
if (encoded && decoded) {
    console.log('成功:', decoded);
}