フロントエンド開発を行うとき、私たちはプロジェクトの最適化に関する 1 つの項目についてよく言及します。それは、小さい画像の場合は、Base64 文字列を使用して埋め込まれた文字列を合理的に置き換えることです。これにより、ページの http リクエストを減らすことができます。
また、画像が小さいこと、サイズが数 KB を超えてはいけないことなどが特に強調されます。
では、Base64 とは一体何なのでしょうか?
事前の理解
次の文字列は誰にとっても非常に一般的なはずです。この固定フォーマットを通じて、画像はブラウザによって表現および認識され、画像を完全に表示できます。
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......
ここに表示されているのは svg 形式の画像です。もちろん、ブラウザがサポートする任意の形式の画像を読み込むこともできます。
この文字列は Base64 に基づいてエンコードされており、base64,
その後ろにある長い文字列は Base64 でエンコードされた文字列です。
Base64の誕生の経緯
インターネット開発の初期には、電子メールが最も効果的なアプリケーションでした。
当初、電子メールの送信プロトコル SMTP は 7 桁の ASCII コードしか送信できず、また ASCII コードは英語をベースに設計されていたため、非英語圏の文字などのリソースを利用できませんでした。送信されます。
この問題を解決するために、その後、メールの主要な構造を追加し、非 ASCII コードのエンコーディング送信規則である Base64 を定義した、一般的なインターネット メール拡張子 MIME が登場しました。文字エンコードに関する知識については、フロントエンド開発で理解しておきたい文字エンコードの知識
をご覧ください。
基本的な定義
Base64 は、64 個の印刷可能な文字に基づいてバイナリ データを表すコーデックです。
コード化およびデコードが可能なため、その主な役割はセキュリティではなく、ゲートウェイ間でコンテンツをエラーなく送信できるようにすることです。
これらの 64 個の印刷可能な文字には、大文字A-Z
、小文字a-z
、数字の0-9
合計 62 文字と、さらに 2 文字 +
と が 含まれます/
。
Base64はインデックスエンコーディングであり、各文字がインデックスに対応しており、具体的な関係図は以下のとおりです。
名前の「64」の由来でもあります。
エンコーディング
64 は 2 の 6 乗に等しいため、Base64 文字は実際には 6 つのバイナリ ビット (ビット) を表します。
ただし、バイナリ データの 1 バイトは 8 ビットに相当するため、3 バイト (3 x 8 = 24 ビット) の文字列/バイナリ データは、4 つの Base64 文字 (4 x 6 = 24 ビット) に変換できます。
なぜ 3 バイトのグループなのでしょうか? 6 と 8 の最小公倍数は 24 であるため、24 ビットはちょうど 3 バイトです。
具体的なエンコード方法は次のとおりです。
- 各 3 バイトを 1 つのグループ、合計 24 のバイナリ ビットを持つ 3 バイトとして扱います。
- これらの 24 ビットを 6 ビットずつの 4 つのグループに分割します。
- 2 進数 6 桁の各グループの前に 2 つの 00 を追加して、2 進数 32 桁、つまり 4 バイトに拡張します。
- 各バイトは、文字番号である 64 未満の数値に対応します。
- 文字インデックス関係表に従い、各文字番号が文字に対応し、Base64でエンコードされた文字が得られます。
上図の文字列は 'you'
変換後、次のようにエンコードされます 'eW91'
。
サイズの増加
3 文字を Base64 でエンコードすると、最終的に 4 文字になることがわかります。各 6 ビットは 2 つの 0 で埋められるため、1 バイトに相当する 8 ビットになります。
これはちょうど 3 分の 1 多いので、通常の状況では、Base64 でエンコードされたデータの量は通常、元のデータの量より 3 分の 1 大きくなります。
画像の最適化に Base64 エンコーディングを使用するという話をしたとき、画像が小さいアイコンであることを強調する必要があるのはこのためです。すべての画像がこの方法を使用すると、静的ファイルが大幅に増加するため、適切ではありません。
= 等号
3 つの英語文字を 4 つの Base64 文字に変換できます。では、文字長が 3 の倍数ではない場合、どのような規則を使用する必要があるのでしょうか。
実はこれも簡単で、実際にBaseエンコードを使ってみると65番目に記号という文字が存在することがよくあるのですが、 '='
この等号はその特殊な状況に対応した処理方法です。
3 バイト未満の場合は、2 進数が 24 ビットになるまで最後に 0 が追加されます。
ただし、バイト数を計算する際は、全長をそのまま3で割ります。余りが1の場合は最後に1を加算し、余りが2の場合は最後に2を加算し=
ます=
。
したがって、以下の図に詳細を示すように、トランスコードされた文字列にはサフィックスの等号 (1 または 2) を追加する必要があります。
図の2番目は 'd'
インデックス文字テーブルのインデックス0を1文字で区別するものですが、このとき取得したコードではインデックス0に対応する文字Aが存在します'='
が2文字追加します。
非 ASCII 文字
エンコードできるのは Base64
文字のみ ASCII
ですので、漢字など非ASCIIコードの場合は、漢字をASCII文字に変換してからエンコードする必要があります。
コーデック方式
btoa と atob
JavaScript には、Base64 エンコードを処理するための 2 つのネイティブ メソッド、btoa()
および が 用意されていますatob()
。
btoa()
: 文字列またはバイナリ値を Base64 でエンコードされた文字列に変換します。
注: btoa メソッドは ASCII コードの文字のみを直接処理でき、非 ASCII コードの文字についてはエラーが報告されます。atob()
: Base64 でエンコードされた文字列をデコードします。
注: atob メソッドが有効な Base64 エンコードではない文字列パラメーター (非 ASCII 文字など) を渡す場合、またはその長さが 4 の倍数ではない場合、エラーが報告されます。
btoa('you') // 'eW91'
atob('eW91') // 'you'
btoa('中') // Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.
atob('y') // Uncaught DOMException: The string to be decoded is not correctly encoded.
漢字を扱う
btoa と atob は ASCII 文字、つまりシングルバイト文字のエンコードのみをサポートしており、通常の中国語文字は 2 ~ 4 バイトであるためです。
したがって、最初に中国語の文字を utf-8
エンコードに変換し、文字として utf-8 エンコードを使用すると、複数の半角文字をエンコードできます。
encodeURIComponent()
中国語の場合は、と の 2 つの方法を使用できます decodeURIComponent()
。
- encodeURIComponent(): 非 ACSII 文字の UTF-8 エンコード
- decodeURIComponent(): を使用したデコード
中国語をエンコードおよびデコードする方法は次のとおりです。
window.btoa(encodeURIComponent('中国'))
// 'JUU0JUI4JUFEJUU1JTlCJUJE'
decodeURIComponent(window.atob('JUU0JUI4JUFEJUU1JTlCJUJE'))
// '中国'
サードパーティのライブラリ
- js-base64
フロントエンド共通アプリケーション
次に、フロントエンド開発における Base64 エンコーディングの一般的な使用シナリオをいくつか理解しましょう。
フロントエンドのBase64のアプリケーションは画像処理が多く、DataURLをベースに利用されるのが一般的です。
データ URL は data:前缀
、、、(テキストの場合はオプション)、および 4 つの部分で構成MIME类型(表明数据类型)
されます 。特定の形式: . データ自体の 4 番目の部分は Base64 文字列です。base64标志位
数据本身
data:[<mime type>][;base64],<data>
<data>
小さな画像のトランスコーディング
つまり、最初に、画像の最適化について、Base64 を使用することでリクエストの数を減らすことができる場合は、img タグの下または CSS 内に置くことができます。
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==">
.icon {
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==);
}
vue または React フレームワークを使用する場合、URL ローダーを通じて設定することもでき、アイコンは Base64 のサイズに変換されます。
.loader('url-loader')
.tap(options => {
options.limit = 10240 // 10kb
return options
})
ファイルの読み取り
Web 環境では、 FileReader
ファイルのデータを読み取るための API が提供されており readAsDataURL()
、そのメソッドを通じてファイル データを Base64 でエンコードされた文字列データとして読み取ることができます。
let reader = new FileReader()
reader.onload = () => {
let base64Img = reader.result
};
reader.readAsDataURL(file)
この方法は、画像のアップロードでよく使用されます。
Canvas が画像を生成する
Canvas は本質的にビットマップ画像であり、 toDataURL()
キャンバスを画像としてエクスポートする方法を提供します。画像は Base64 エンコード形式で保存されます。
const dataUrl = canvasEl.toDataURL()
// data:image/png;base64,PHN2ZyB4bWxucz0iaHR0c......
他の
画像表示の処理に加えて、特別なデータ送信、単純なエンコードと暗号化、コード難読化、および一部の証明書における Base64 エンコード文字列も表示されます。
要約する
最後に、Base64 の特徴をまとめてみましょう。
- バイナリデータを文字列(ASCIIコード)に変換してデータ送信を容易にします。
- ブラウザーは Base64 でエンコードされた画像を直接表示できるため、リクエストが削減されます。
- エンコード後のデータは少なくとも 3 分の 1 大きくなり、エンコードとデコードを処理するには追加のメソッドが必要になります。