🔄 Node-RED base64 ノードガイド
📦 パッケージ情報:
- パッケージ名: node-red-node-base64
- 種別: Node-RED公式アドオンノード(node-red-nodesコレクション)
- カテゴリ: parser
- ライセンス: Apache-2.0
📖 1. 概要
node-red-node-base64は、Base64エンコード/デコードを行うパーサーノードです。バイナリデータ(Buffer)とBase64文字列を相互変換します。
Base64とは
Base64は、バイナリデータをASCII文字列に変換するエンコード方式です。画像やファイルなどのバイナリデータを、テキストベースのプロトコル(JSON、HTTP、MQTT等)で安全に送受信するために使用されます。
Buffer(バイナリ)
⇅ base64ノード
Base64文字列
なぜBase64が必要なのか
通信の安全性を確保するため
メールのSMTP、JSON、HTTPなど、本来テキストしか扱えないプロトコルでバイナリデータをそのまま送ると、制御文字と誤認されてデータが壊れることがあります。Base64を使えば、すべてのデータを「安全なASCII文字」に変換できるため、どのプロトコルでも確実にデータを送受信できます。
荷物の梱包に例えると
- エンコード(Buffer → Base64)= 壊れやすい荷物を緩衝材で包んで安全に送れる形にする
- デコード(Base64 → Buffer)= 届いた荷物から緩衝材を外して中身を取り出す
バイナリデータ
→
base64
→
debug
🔧 2. インストール
方法1: パレットマネージャー(推奨)
- Node-REDエディタのメニュー → パレットの管理
- ノードを追加タブを選択
node-red-node-base64 を検索
- ノードを追加ボタンをクリック
方法2: コマンドライン
cd ~/.node-red
npm install node-red-node-base64
インストール後、Node-REDを再起動するとパレットの「parser」カテゴリにノードが追加されます。
⚙️ 3. ノード設定プロパティ
| プロパティ |
型 |
デフォルト |
説明 |
| Action |
select |
Convert to/from buffer |
変換モード(自動判定 / エンコード / デコード) |
| Property |
typedInput |
msg.payload |
操作対象のメッセージプロパティ |
| Name |
string |
(空) |
エディタ上での表示名 |
Actionモードの詳細
| モード |
動作 |
用途 |
| Convert to/from buffer(自動判定) |
入力の型に応じてエンコードまたはデコードを自動選択 |
汎用的な変換処理 |
| Encode to base64 |
入力を常にBase64文字列にエンコード |
確実にBase64化したい場合 |
| Decode from base64 |
入力を常にBase64からデコード |
確実にデコードしたい場合 |
🔀 4. 変換動作の詳細
自動判定モード(デフォルト)の動作
| 入力データの型 |
出力結果 |
説明 |
| Buffer(バイナリ) |
Base64文字列 |
バイナリデータをBase64にエンコード |
| 有効なBase64文字列 |
Buffer(バイナリ) |
Base64文字列をバイナリにデコード |
| 通常の文字列 |
Base64文字列 |
文字列をBase64にエンコード |
💡 有効なBase64文字列の判定条件:
- 使用文字:
A-Z, a-z, 0-9, +, /, = のみ
- 文字列長が4の倍数であること
- 入力前にスペース・改行等の空白文字は自動的に除去される
変換の具体例
エンコード(文字列 → Base64)
入力: "Hello, Node-RED!"
出力: "SGVsbG8sIE5vZGUtUkVEIQ=="
エンコード(Buffer → Base64)
入力: Buffer.from([0x89, 0x50, 0x4E, 0x47]) // PNGヘッダー
出力: "iVBORw=="
デコード(Base64 → Buffer)
入力: "SGVsbG8sIE5vZGUtUkVEIQ=="
出力: Buffer <48 65 6c 6c 6f 2c 20 4e 6f 64 65 2d 52 45 44 21>
("Hello, Node-RED!" のバイナリ表現)
Propertyの設定
デフォルトではmsg.payloadを変換しますが、任意のプロパティを指定できます。
// 例: msg.data.image を変換対象に設定
// Property欄に "msg.data.image" を指定
// 入力
msg.data = {
image: Buffer.from(imageData),
name: "photo.png"
};
// base64ノード通過後
msg.data = {
image: "iVBORw0KGgoAAAANSUhEUg...", // Base64文字列に変換
name: "photo.png" // 他のプロパティはそのまま
};
🛠️ 5. 実用的な使用パターン
パターン1: 画像ファイルをBase64に変換してAPI送信
画像ファイルを読み込み、Base64に変換してREST APIに送信します。
file read
→
base64
→
JSON作成
→
http request
// Functionノード: Base64画像をJSON APIに送信
msg.payload = {
"image": msg.payload, // base64ノードで変換済み
"filename": msg.filename || "image.png",
"timestamp": new Date().toISOString()
};
msg.headers = { "Content-Type": "application/json" };
return msg;
パターン2: HTMLに画像を埋め込む(Data URI)
画像をBase64に変換し、Data URIとしてHTMLに直接埋め込みます。
file read
→
base64
→
HTML生成
→
debug
// Functionノード: Data URI形式に変換
var mimeType = "image/png"; // 画像の種類に応じて変更
var dataUri = "data:" + mimeType + ";base64," + msg.payload;
msg.payload = '<img src="' + dataUri + '" alt="embedded image">';
return msg;
パターン3: MQTTでバイナリデータを送受信
バイナリデータをBase64にエンコードしてMQTTで送信し、受信側でデコードします。
送信側
バイナリ生成
→
base64
→
MQTT out
受信側
MQTT in
→
base64
→
バイナリ処理
// 送信側Functionノード: センサーデータをバイナリパケットに
var buf = Buffer.alloc(8);
buf.writeFloatLE(25.5, 0); // 温度
buf.writeFloatLE(60.2, 4); // 湿度
msg.payload = buf;
// → base64ノードでエンコードされてMQTTで送信
return msg;
// 受信側Functionノード: デコード後のバイナリパケットを解析
// base64ノードでBuffer化済み
var buf = msg.payload;
var temp = buf.readFloatLE(0);
var humidity = buf.readFloatLE(4);
msg.payload = {
temperature: Math.round(temp * 10) / 10,
humidity: Math.round(humidity * 10) / 10
};
return msg;
パターン4: メール添付画像のデコード
受信メールの添付ファイル(Base64)をデコードしてファイルに保存します。
添付取得
→
base64
→
file write
// Functionノード: メール添付ファイルの処理
if (msg.attachments && msg.attachments.length > 0) {
var att = msg.attachments[0];
msg.payload = att.content; // Base64文字列
msg.filename = "/tmp/" + att.fileName;
return msg;
}
return null;
パターン5: カメラ画像のダッシュボード表示
HTTPリクエストで取得した画像をBase64に変換し、ダッシュボードのTemplateノードで表示します。
定期取得
→
カメラ画像取得
→
base64
→
ui-template
// http requestノードの設定:
// URL: http://camera-ip/snapshot.jpg
// Method: GET
// Return: a binary buffer
// base64ノードで自動的にBufferからBase64文字列に変換される
// ui-templateノード:
// <img src="data:image/jpeg;base64,{{msg.payload}}"
// style="width:100%; max-width:640px;">
📝 6. 演習問題
演習1: テキストのBase64変換初級
課題:
テキスト文字列をBase64にエンコードし、さらにデコードして元に戻るフローを作成してください。
要件:
- Injectノードで「Node-RED Base64 テスト」というテキストを送信
- 1つ目のbase64ノードでエンコード
- 2つ目のbase64ノードでデコード
- 各段階でDebugノードに出力して変換結果を確認
✅ 成功の条件:
- エンコード後のDebugノードに「Tm9kZS1SRUQgQmFzZTY0IO...」のようなBase64文字列(英数字と+/=のみで構成)が表示される
- Base64文字列の末尾が
=または==でパディングされている(元の文字数によって異なる)
- デコード後のDebugノードに「Node-RED Base64 テスト」という元の文字列が表示される
- エンコード→デコードの往復で元のテキストと完全に一致する
💡 ヒント
- Injectノードの
msg.payloadを文字列型で設定
- base64ノードはデフォルト(自動判定)モードで動作する
- 1つ目のDebugではBase64文字列が表示される
- 2つ目のDebugではBufferが表示される(
.toString()で文字列に戻る)
✅ 解答例フロー
[
{
"id": "b64_ex1_inject",
"type": "inject",
"name": "テスト文字列",
"props": [{"p": "payload"}],
"payload": "Node-RED Base64 テスト",
"payloadType": "str",
"wires": [["b64_ex1_encode"]]
},
{
"id": "b64_ex1_encode",
"type": "base64",
"name": "エンコード",
"action": "",
"property": "payload",
"wires": [["b64_ex1_debug1", "b64_ex1_decode"]]
},
{
"id": "b64_ex1_debug1",
"type": "debug",
"name": "Base64文字列",
"active": true,
"complete": "payload",
"wires": []
},
{
"id": "b64_ex1_decode",
"type": "base64",
"name": "デコード",
"action": "",
"property": "payload",
"wires": [["b64_ex1_func"]]
},
{
"id": "b64_ex1_func",
"type": "function",
"name": "Buffer→文字列",
"func": "msg.payload = msg.payload.toString();\nreturn msg;",
"wires": [["b64_ex1_debug2"]]
},
{
"id": "b64_ex1_debug2",
"type": "debug",
"name": "復元結果",
"active": true,
"complete": "payload",
"wires": []
}
]
演習2: 画像ファイルのBase64変換中級
課題:
画像ファイルを読み込んでBase64に変換し、Data URI形式のHTMLを生成するフローを作成してください。
要件:
- Read Fileノードで画像ファイル(PNG/JPEG)をバイナリとして読み込み
- base64ノードでBuffer→Base64文字列に変換
- Functionノードで
data:image/png;base64,...形式のHTMLを生成
- Debugノードで生成されたHTMLを確認
✅ 成功の条件:
- Debugノードに
data:image/png;base64,iVBORw0KGgo...のようなData URI形式の文字列が表示される
- 出力文字列が
<html><body>で始まり、<img src="data:image/...;base64,を含むHTMLになっている
- 生成されたHTMLをブラウザで開くと、外部ファイル参照なしに画像が表示される
- Base64文字列部分が英数字と
+/=のみで構成された有効なBase64形式になっている
💡 ヒント
- Read Fileノードの出力を「a binary buffer」に設定
- base64ノードは自動判定モードでBufferを検知してエンコードする
- Data URIの形式:
data:[MIME型];base64,[Base64文字列]
- PNGは
image/png、JPEGはimage/jpeg
✅ 解答例フロー
[
{
"id": "b64_ex2_inject",
"type": "inject",
"name": "読み込み開始",
"props": [{"p": "filename", "v": "/tmp/test.png", "vt": "str"}],
"wires": [["b64_ex2_file"]]
},
{
"id": "b64_ex2_file",
"type": "file in",
"name": "画像読み込み",
"filename": "",
"filenameType": "msg",
"format": "",
"allProps": true,
"wires": [["b64_ex2_base64"]]
},
{
"id": "b64_ex2_base64",
"type": "base64",
"name": "Base64変換",
"action": "",
"property": "payload",
"wires": [["b64_ex2_func"]]
},
{
"id": "b64_ex2_func",
"type": "function",
"name": "Data URI HTML生成",
"func": "var ext = (msg.filename || '').split('.').pop().toLowerCase();\nvar mimeMap = { 'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'gif': 'image/gif' };\nvar mime = mimeMap[ext] || 'image/png';\n\nvar dataUri = 'data:' + mime + ';base64,' + msg.payload;\nmsg.payload = '
Base64埋め込み画像

';\nreturn msg;",
"wires": [["b64_ex2_debug"]]
},
{
"id": "b64_ex2_debug",
"type": "debug",
"name": "HTML出力",
"active": true,
"complete": "payload",
"wires": []
}
]
演習3: MQTTによるバイナリデータ送受信上級
課題:
バイナリ構造体データをBase64エンコードしてMQTTで送信し、受信側でデコードして解析するフローを作成してください。
要件:
- 送信側: Functionノードでセンサーデータ(温度・湿度・気圧)をバイナリパケットに変換
- 送信側: base64ノードでエンコード後にMQTT outで送信
- 受信側: MQTT inで受信後にbase64ノードでデコード
- 受信側: Functionノードでバイナリパケットを解析してJSON形式に変換
- Debugノードで解析結果を確認
✅ 成功の条件:
- 「Base64パケット」Debugノードに16文字程度の有効なBase64文字列(英数字と
+/=のみ)が表示される
- 「解析結果」Debugノードに
{"temperature": 25.5, "humidity": 60.2, "pressure": 1013.25}のようなJSONオブジェクトが表示される
- デコード後の各値(temperature/humidity/pressure)が元のバイナリパックの値と一致する(浮動小数点の誤差は許容範囲内)
- Base64エンコード→デコード→バイナリ解析の全工程でエラーが発生しない
💡 ヒント
Buffer.alloc(12)で12バイトのバッファを作成(Float32×3)
buf.writeFloatLE(value, offset)で浮動小数点数を書き込み
buf.readFloatLE(offset)で読み取り
- オフセット: 温度=0, 湿度=4, 気圧=8
✅ 解答例フロー
[
{
"id": "b64_ex3_inject",
"type": "inject",
"name": "センサー送信",
"props": [],
"repeat": "",
"wires": [["b64_ex3_pack"]]
},
{
"id": "b64_ex3_pack",
"type": "function",
"name": "バイナリパック",
"func": "var buf = Buffer.alloc(12);\nbuf.writeFloatLE(25.5, 0); // 温度\nbuf.writeFloatLE(60.2, 4); // 湿度\nbuf.writeFloatLE(1013.25, 8); // 気圧\nmsg.payload = buf;\nreturn msg;",
"wires": [["b64_ex3_encode"]]
},
{
"id": "b64_ex3_encode",
"type": "base64",
"name": "エンコード",
"action": "",
"property": "payload",
"wires": [["b64_ex3_debug_enc", "b64_ex3_decode"]]
},
{
"id": "b64_ex3_debug_enc",
"type": "debug",
"name": "Base64パケット",
"active": true,
"complete": "payload",
"wires": []
},
{
"id": "b64_ex3_decode",
"type": "base64",
"name": "デコード",
"action": "",
"property": "payload",
"wires": [["b64_ex3_unpack"]]
},
{
"id": "b64_ex3_unpack",
"type": "function",
"name": "バイナリ解析",
"func": "var buf = msg.payload;\nmsg.payload = {\n temperature: Math.round(buf.readFloatLE(0) * 10) / 10,\n humidity: Math.round(buf.readFloatLE(4) * 10) / 10,\n pressure: Math.round(buf.readFloatLE(8) * 100) / 100\n};\nreturn msg;",
"wires": [["b64_ex3_debug_dec"]]
},
{
"id": "b64_ex3_debug_dec",
"type": "debug",
"name": "解析結果",
"active": true,
"complete": "payload",
"wires": []
}
]
🔧 7. トラブルシューティング
| 問題 |
原因 |
解決方法 |
| デコード結果が文字化けする |
元データの文字エンコーディングが異なる |
デコード後にbuf.toString('utf-8')で正しいエンコーディングを指定する |
| 「Not a valid base64 string」エラー |
入力がBase64形式ではない、または不正な文字を含む |
入力データが有効なBase64か確認する。改行やスペースは自動除去されるが、不正文字は除去されない |
| エンコードされずにそのまま通過する |
入力が有効なBase64文字列と判定されデコードされた |
Actionを「Encode to base64」に明示的に設定する |
| 出力がBufferになってしまう |
Base64文字列がデコードされてBufferになった |
文字列が必要な場合は後段のFunctionノードで.toString()を実行する |
| ノードがパレットに表示されない |
インストール失敗またはNode-RED未再起動 |
npm installのエラーログを確認し、Node-REDを再起動する |
| 大きなファイルで処理が遅い |
Base64変換はデータサイズが約33%増加する |
大きなバイナリデータは直接Bufferで処理し、Base64は転送時のみ使用する |
📝 8. ベストプラクティス
✅ 推奨事項:
- Actionモードの明示的設定: 意図した変換方向が決まっている場合は自動判定ではなく明示的にEncode/Decodeを指定する
- データサイズの考慮: Base64はデータを約33%増加させるため、大量のバイナリデータには不向き。必要な場合のみ使用する
- MIME型の管理: 画像をBase64化する際はMIME型(image/png等)を別プロパティで保持しておく
- Bufferの文字列化: デコード後のBufferを文字列として使う場合は
toString('utf-8')を明示する
- 用途の明確化: Base64は「テキストチャネルでバイナリを送る」ための手段。バイナリ対応プロトコルではそのままBufferを使うほうが効率的
⚠️ 注意事項:
- 自動判定の罠: 偶然Base64パターンに一致する通常文字列(英数字のみ+長さが4の倍数)は誤ってデコードされる可能性がある
- メモリ使用量: 大きなファイル(数十MB以上)のBase64変換はNode.jsのメモリを圧迫する可能性がある
- セキュリティ: Base64は暗号化ではなくエンコードに過ぎない。機密データの保護には別途暗号化が必要
🔗 9. 追加リソース
🏠