はじめに (対象読者・この記事でわかること)
この記事は、Node.js(特に Express)でサーバーサイド開発を行っているエンジニアや、フロントエンドとバックエンドの連携に悩んでいる方を対象としています。
具体的には、HTML の <textarea> に name 属性を付与してもサーバー側で undefined と表示される現象の原因を明らかにし、正しいミドルウェア設定とフォームの書き方をマスターできるようになります。
実際に自分のプロジェクトで同様の不具合が起きたときに、すぐに原因を特定し修正できる知識が身につくので、デバッグ時間の短縮とコードの安定性向上が期待できます。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- HTML の基本的な構造とフォーム要素(<form>, <input>, <textarea> など)
- Node.js と Express の基礎、特に app.use() でミドルウェアを組み込む方法
- body-parser(もしくは Express 標準の express.urlencoded)の役割
概要・背景
Web アプリケーションでユーザーからのテキスト入力を受け取る際、<textarea name="comment"> のように name 属性を付与します。サーバー側では req.body.comment で取得できるはずですが、「undefined が返ってくる」という報告が散見されます。
この症状は、単にフロントエンドの記述ミスだけでなく、Node.js 側のミドルウェア設定ミスや enctype の指定漏れ、さらには文字コードの問題まで多岐にわたります。
本稿では、実際に起こりうるパターンを洗い出し、最も一般的な原因とその回避策をステップバイステップで解説します。まずは原因を体系的に整理し、次に具体的なコード例とテスト方法を示すことで、読者が同様のバグに遭遇した際に即座に対処できるように導きます。
具体的な手順や実装方法
ステップ1 HTML 側の正しい記述
Html<form action="/submit" method="POST" enctype="application/x-www-form-urlencoded"> <label for="msg">メッセージ</label> <textarea id="msg" name="message" rows="5" cols="40"></textarea> <button type="submit">送信</button> </form>
name属性は必ず小文字・英数字で統一する。大文字混在や日本語は避ける。enctypeが省略された場合、デフォルトはapplication/x-www-form-urlencodedになるが、明示すると意図が明確になる。<textarea>の中にデフォルトテキストを入れたくない場合は、空のままにし、value属性は使用しない点に注意。
ステップ2 Express 側のミドルウェア設定
Jsconst express = require('express'); const app = express(); // 1. urlencoded ミドルウェアを必ず先に呼び出す app.use(express.urlencoded({ extended: false })); // extended: false で querystring パーサー使用 // 2. 必要に応じて json パーサーも登録 app.use(express.json()); app.post('/submit', (req, res) => { console.log('受け取ったデータ:', req.body); // 期待: { message: 'ユーザーが入力したテキスト' } res.send(`受領しました: ${req.body.message || 'データがありません'}`); }); app.listen(3000, () => console.log('Server listening on http://localhost:3000'));
express.urlencoded()が未設定だと、req.bodyが空オブジェクトになるかundefinedが返ります。extended: trueにするとqsライブラリが使用され、ネストしたオブジェクトを扱えるが、シンプルなフォームならfalseで十分です。- もし
multipart/form-data(ファイルアップロード等)を使用する場合はmulterなど別のミドルウェアが必要です。
ハマった点やエラー解決
| 現象 | 原因例 | 解決策 |
|---|---|---|
req.body.message が undefined |
express.urlencoded が未設定 |
app.use(express.urlencoded({ extended: false })); を追加 |
req.body が空オブジェクト |
フォームに enctype="multipart/form-data" が設定されている |
multer を導入し、upload.none() でテキストだけ受け取る |
| 日本語が文字化け | charset が明示されていない、もしくは body-parser のデフォルトが UTF-8 でない |
<meta charset="UTF-8"> を HTML の <head> に追加し、サーバー側は特に設定不要 |
<textarea> が空でも undefined |
name 属性にスペルミス(例: nam) |
正しい属性名 name="message" に修正 |
req.body が null |
express.json() と express.urlencoded() を逆順で登録した場合 |
ミドルウェアは 必ず上から順に 登録し、urlencoded を先に |
解決策
最も頻繁に見られる原因は 「express.urlencoded が呼び出されていない」 です。
1. app.use(express.urlencoded({ extended: false })); を サーバー起動直後に 追加し、他のルーティングより前に配置します。
2. HTML 側で enctype が正しく指定されているか確認し、multipart/form-data が不要な場合は application/x-www-form-urlencoded に統一します。
3. name 属性のスペルミスや大文字・日本語使用がないか最終チェックします。
上記を順守すれば、req.body.message が正しく取得でき、undefined エラーは解消されます。
まとめ
本記事では、Node.js(Express)で <textarea> の name 属性が undefined と出力される 問題の原因と対策を体系的に解説しました。
- 原因1:
express.urlencodedの未設定または順序ミス - 原因2:HTML の
enctypeとname属性の記述不備 - 原因3:
multipart/form-dataとミドルウェアの不整合
これらを正しく設定すれば、サーバー側でテキストデータを確実に取得でき、デバッグ時間を大幅に短縮できます。次回は、ファイルアップロードを伴う multipart/form-data のハンドリング について詳しく解説する予定です。
参考資料
- Express 公式ドキュメント –
express.urlencoded - MDN Web Docs –
<textarea>要素 - body-parser パッケージ(非推奨)
- Multer – ミドルウェア for multipart/form-data