読み込み中...

HTMLで簡単に実現!郵便番号から住所を自動入力する方法5選

郵便番号入力フォームのイメージ図 HTML
この記事は約18分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

郵便番号から住所を自動入力する結論

郵便番号から住所を自動入力するフォームは、既存ライブラリ、公開API、住所マスタ、サーバー側検索、EC向け住所補完サービスのいずれかで実装できます。入力欄にautocompleteinputmodeを加え、郵便番号の表記ゆれをreplace()で整えてから検索すると、初心者がつまずきやすい入力ミスを減らしやすくなります。

そのため、小規模な問い合わせフォームならライブラリ方式、会員登録や購入フォームならAPI方式、社内システムなら住所マスタ方式が扱いやすい選択になるのが基本です。フォーム全体の作り方はHTMLで問い合わせフォームを作成する方法5選!も参考になり、郵便番号入力欄だけを孤立させずに設計できます。

動作確認環境
  • HTML Living Standard
  • JavaScript ECMAScript 2024 相当
  • Google Chrome 126 / Firefox 127 / Safari 17
📖 この記事で学べること
  • 郵便番号から住所を自動入力する代表的な実装方式
  • 入力欄に必要なnameautocompletepatternの考え方
  • ライブラリ方式とAPI方式の使い分け
  • 住所マスタを使う場合の更新と運用の注意点
  • アクセシビリティとセキュリティを崩さないフォーム設計

実装方式の早見表

具体的には、郵便番号から住所を自動入力する仕組みは、外部の郵便番号データを直接引く方式と、自サイト側で住所データを持つ方式に分かれます。どの方式でもinputlabelidforの対応を崩さず、利用者が手入力で修正できる余地を残す設計が現実的です。

一方、住所の自動入力は入力補助であり、確定処理ではありません。郵便番号の変更、同一郵便番号に複数の町域があるケース、事業所個別番号などがあるため、readonlyで固定するよりvalueを自動反映した後に編集可能にする形が扱いやすくなります。

方式向いている画面主な構成注意点判断の目安
ライブラリ方式問い合わせフォームscriptと入力欄外部配信元の停止に備える短期間で導入しやすい
公開API方式会員登録fetch()とJSON通信失敗時の表示が必要画面制御を細かく作れる
住所マスタ方式社内管理画面DBと検索処理データ更新が必要外部依存を減らせる
サーバー仲介方式ECサイト自社APIとキャッシュレスポンス設計が必要アクセス量が多い画面向き
クラウド補完方式決済フォームSaaS SDK費用と規約を確認する入力体験を整えやすい
都道府県のみ補完簡易フォーム郵便番号上位桁の判定市区町村までは補完しない最小限の補助に向く
候補選択方式同一番号が多い地域selectと候補配列候補の表示順を決める誤った町域確定を防げる
手入力併用方式高齢者向けフォーム補完ボタンと手入力自動反映の説明を短くする利用者の混乱を減らせる
郵便番号分割入力古い業務画面maxlengthと複数欄コピー入力に弱い既存画面の制約がある場合
郵便番号単一入力スマートフォン画面inputmodeと正規化ハイフン処理が必要現在のフォームで扱いやすい
ボタン起動方式明示操作が必要な画面buttonとクリック処理押し忘れに備える自動通信を避けたい場合
入力完了時起動登録フォームinputイベント通信回数を抑える自然な自動入力に向く
フォーカス外れ起動業務フォームblurイベント遅れて反映される誤通信を抑えやすい
住所欄分割配送先登録都道府県、市区町村、番地後続入力の設計が必要配送処理と相性がよい
住所欄一体型簡易問い合わせtextareaまたは単一欄構造化しにくい管理用途が軽い場合
郵便番号バリデーション全フォームpatternとJS判定形式だけでは存在確認できない入力ミス対策になる
エラー表示付き検索会員登録aria-liveとメッセージ断定的な文言を避ける支援技術へ伝えやすい
キャッシュ併用高頻度入力画面Mapと保存処理古いデータに注意する同じ番号の再検索を減らせる
郵便番号CSV取込バックオフィス定期更新バッチ文字コードに注意する管理画面と相性がよい
Web Component化複数画面customElements対応範囲を確認する部品化したい場合
フレームワーク組込SPAReactやVueの状態管理再レンダリングを考慮する既存構成に合わせやすい
サーバーレンダリング公共系フォームサーバー側テンプレートページ遷移が発生するJS無効時にも対応しやすい
プログレッシブ強化広い利用者層通常入力とJS補助補助なしでも完了可能にする堅実な設計になる
住所候補の手動選択町域候補が多い地域option配列候補名を省略しない誤選択を減らせる
入力ログ非保存個人情報画面最小限の通信プライバシーポリシーを確認する個人情報保護に向く
管理者確認方式BtoB登録補完後の確認欄利用者の手間が増える正確性を重視する場合
多言語住所対応海外向け画面langと国別入力日本式郵便番号だけにしない越境EC向き
法人住所補完請求先登録法人DB連携表記ゆれが残る会社情報入力を軽くできる
番地未入力検知配送先登録送信前チェック過剰な警告を避ける配送ミスを減らせる
オフライン非対応一般Webフォーム通信前提圏外時の導線が必要通常の公開サイト向き

郵便番号入力欄の設計

一般に、郵便番号はハイフンありの123-4567とハイフンなしの1234567が混在します。そのため、画面側ではtype="text"を使い、inputmode="numeric"で数字キーボードを促しながら、JavaScriptでハイフンを取り除いて検索値を作る設計が安定します。

このとき、type="number"は先頭のゼロやハイフンの扱いで期待とずれる場合があるのが目安です。郵便番号は計算対象ではなく識別子なので、maxlengthplaceholderautocomplete="postal-code"を組み合わせ、利用者が入力内容を確認しやすい状態にします。

💡 Tips: 入力補助の属性はフォームの品質を底上げします。autocompleteの値は、MDNのautocomplete属性リファレンスで確認できるのがポイントです。
<label for="zip">郵便番号</label>
<input
  id="zip"
  name="postal_code"
  type="text"
  inputmode="numeric"
  autocomplete="postal-code"
  placeholder="123-4567"
  maxlength="8"
>

<label for="address">住所</label>
<input
  id="address"
  name="street_address"
  type="text"
  autocomplete="street-address"
>

結果: 期待される表示は、郵便番号の入力欄と住所の入力欄がラベル付きで並ぶ形です。スマートフォンでは数字入力に適したキーボードが出やすくなり、ブラウザの自動補完とも連携しやすくなります。

ただし、maxlength="8"はハイフンありを想定した長さです。ハイフンなしだけを許容するならmaxlength="7"に変わりますが、コピーした郵便番号をそのまま貼り付けられる余地を残すなら、正規化処理で吸収するほうが使いやすくなります。

方法1:ライブラリで自動入力する

これが最短で導入しやすい方式です。郵便番号から住所を自動入力する既存ライブラリは、指定した入力欄を監視して住所欄へ値を入れるため、フォームが小さい場合は少ない記述で動かせますし、ここがポイントです。

その反面、外部スクリプトに依存するため、配信元の障害や仕様変更に備えて、手入力で送信できるフォームを保つ必要があります。HTMLとJSを使ってカレンダーを作成・更新する方法10選のように、画面上の入力とJavaScriptの状態が連動する構成を理解しておくと、住所欄への反映処理も読みやすくなります。

<input type="text" name="zip" class="js-zip" autocomplete="postal-code">
<input type="text" name="address" class="js-address" autocomplete="street-address">

<script src="https://yubinbango.github.io/yubinbango/yubinbango.js"></script>

結果: 期待される表示は、郵便番号欄と住所欄が表示され、ライブラリの仕様に沿ったクラス名や属性が整っている場合に住所欄へ候補が反映される状態です。実際の動作は読み込むライブラリの仕様と配信状況に左右されますが、これは押さえたい点です。

基本的に、ライブラリ方式はフォームの構造をライブラリ側の前提に合わせる必要があります。クラス名やnameが少し違うだけで自動入力されないことがあるため、導入時は公式のサンプルと入力欄の対応を確認する流れになります。

方法2:公開APIをfetchで呼び出す

その場で住所検索の状態を細かく制御したい場合は、公開APIをfetch()で呼び出す方式が向いているのが一般的です。郵便番号を正規化し、レスポンスのstatusresultsを見て、住所欄とメッセージ欄を更新する流れになります。

ただし、公開APIには利用規約、レート制限、障害時の挙動があります。住所の自動入力が送信完了の前提にならないように、検索できない場合でもdisabledにせず、利用者が手入力で先へ進める設計にするのが現実的です。

<label for="zip-api">郵便番号</label>
<input id="zip-api" type="text" inputmode="numeric" autocomplete="postal-code">

<label for="address-api">住所</label>
<input id="address-api" type="text" autocomplete="street-address">

<p id="zip-message" aria-live="polite"></p>

<script>
const zipInput = document.querySelector('#zip-api');
const addressInput = document.querySelector('#address-api');
const message = document.querySelector('#zip-message');

zipInput.addEventListener('blur', async () => {
  const zip = zipInput.value.replace(/[^0-9]/g, '');

  if (zip.length !== 7) {
    message.textContent = '郵便番号は7桁で入力してください。';
    return;
  }

  try {
    const response = await fetch(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${zip}`);
    const data = await response.json();

    if (!data.results) {
      message.textContent = '住所候補が見つかりません。手入力してください。';
      return;
    }

    const result = data.results[0];
    addressInput.value = `${result.address1}${result.address2}${result.address3}`;
    message.textContent = '住所候補を入力しました。番地以降を確認してください。';
  } catch (error) {
    message.textContent = '住所検索に接続できません。手入力してください。';
  }
});
</script>

結果: 期待される表示は、郵便番号欄からフォーカスが外れた後に住所候補が住所欄へ入る形です。通信に失敗した場合は、利用者へ手入力を促すメッセージが表示される想定になります。

このとき、aria-live="polite"をメッセージ欄に付けると、支援技術へ検索結果を伝えやすくなります。アクセシビリティの基礎は、WHATWGのフォーム自動補完の仕様やMDNのaria-live属性を確認すると整理しやすいです。

⚠️ 注意: 外部APIのレスポンスを無条件に信頼して送信済み扱いにしないでください。住所は利用者が確認し、番地や建物名を追記できる入力欄として残す設計が安全です。

方法3:住所マスタをサーバー側で検索する

これらの外部依存を減らしたい場合は、日本郵便などが提供する郵便番号データを取り込み、サーバー側で住所を検索する方式があります。社内システムや管理画面では、ネットワーク制約や外部サービスの規約に左右されにくい構成として採用しやすいです。

一方、住所マスタ方式には更新作業が伴います。郵便番号や町域は変更されるため、CSV取込、差分更新、文字コード変換、検索インデックスの再生成を運用に含める必要があると整理できます。

具体的には、フロントエンドから/api/addressのような自社APIへ郵便番号を送り、サーバー側でDB検索してJSONを返します。レスポンスはprefecturecitytownのように分けると、住所欄を分割しているフォームにも流用しやすくなります。

// レスポンス例
{
  "postalCode": "1000001",
  "prefecture": "東京都",
  "city": "千代田区",
  "town": "千代田"
}

結果: 期待される出力は、郵便番号に対応する都道府県、市区町村、町域がJSONで返る形です。画面側ではこの値を結合するか、分割された入力欄へそれぞれ入れる処理になると理解できます。

そのため、住所マスタ方式では検索精度だけでなく、データ更新日を管理画面に表示する設計も有効です。管理者が古いデータに気づける状態にしておくと、利用者からの問い合わせ時にも原因を追いやすくなります。

方法4:フォーム内で候補を選ばせる

同じ郵便番号に複数の住所候補がある地域では、自動入力で一意に決めるより、候補を表示して選ばせるほうが誤入力を抑えやすくなります。selectやラジオボタンで候補を提示し、選択後に住所欄へ反映する形が扱いやすいです。

このとき、候補名を省略しすぎると利用者が判断できません。都道府県、市区町村、町域を一文で表示し、番地以降は別のinputへ入力してもらう構成にすると、配送や請求先の処理にもつなげやすくなると覚えるとよいでしょう。

<label for="address-candidate">住所候補</label>
<select id="address-candidate" name="address_candidate">
  <option value="">候補を選択してください</option>
  <option value="東京都千代田区千代田">東京都千代田区千代田</option>
  <option value="東京都千代田区丸の内">東京都千代田区丸の内</option>
</select>

<label for="address-detail">番地・建物名</label>
<input id="address-detail" name="address_detail" type="text" autocomplete="address-line2">

結果: 期待される表示は、住所候補の選択欄と番地・建物名の入力欄が分かれたフォームです。候補を選んだ後も番地以降を手入力できるため、自動入力だけでは埋まらない情報を補えます。

使い分けると、候補選択方式は正確性を重視する登録フォームに向いています。入力欄が増えるため画面は少し長くなりますが、住所の町域が誤って確定されるリスクを下げやすい構成です。

方法5:ECや会員登録向けに補完サービスを使う

ECサイトや会員登録では、郵便番号から住所を自動入力するだけでなく、入力途中の候補表示、法人住所補完、番地未入力の警告なども求められることがあると考えられます。その場合は、住所補完に特化したクラウドサービスやSDKを検討する余地があります。

ただし、外部サービスへ送るデータの範囲、保存期間、利用規約、料金体系を確認しなければなりません。住所は個人情報に該当し得るため、必要な通信だけに絞り、プライバシーポリシーとの整合を取る必要があります。

実際、決済前のフォームでは入力完了率と入力精度の両方が問題になると言えるでしょう。郵便番号、都道府県、市区町村、番地、建物名の分割を明確にし、誤りがある場合はsetCustomValidity()reportValidity()で利用者へ伝えると、標準のフォーム検証とも合わせやすくなります。

ℹ️ 補足: フォーム部品の属性や入力補助は、画面の見た目だけでなく送信データの品質にも影響します。アンカーリンクで入力エラー位置へ移動させたい場合は、『HTMLでアンカーリンクを活用する方法10選の考え方も応用できるのが基本です。

住所欄を分割するか一体にするか

基本的に、配送や請求処理に使う住所は、都道府県、市区町村、町域、番地、建物名に分けるほうが後続処理で扱いやすくなります。都道府県だけをselectにし、市区町村以降をinputにする構成もよく使われます。

一方、問い合わせフォームのように住所が任意項目で、管理側が文章として読むだけなら単一欄でも足りますし、これが一つの目安です。textareaを使う場合は自由度が上がりますが、郵便番号から自動入力した値と利用者の追記を区別しにくくなる点に注意します。

そのため、データを機械的に処理するなら分割、担当者が読むだけなら一体型という判断が現実的です。スライドや管理画面のようにUI部品を組み合わせる考え方は、HTMLとCSSで手軽に作るスライドショーコピペ12選にも通じます。

エラー表示とアクセシビリティ

郵便番号検索では、未入力、桁数不足、該当なし、通信失敗の状態を分けて伝える必要があるのが目安です。すべてを「エラー」と表現すると利用者が原因を判断しにくいため、形式の問題か、住所候補が見つからない問題か、通信の問題かを文面で切り分けます。

このとき、メッセージ欄にはrole="status"aria-liveを使えます。赤字だけで状態を伝えると色覚特性によって読み取りにくくなる場合があるため、文言、アイコン、入力欄との近さを組み合わせる構成が扱いやすいです。

ただし、住所の自動入力が失敗しただけで送信ボタンを押せなくするのは避けたい設計です。郵便番号データに未反映の住所や新しい建物もあるため、利用者が手入力で補完できる逃げ道を残するのがポイントです。

セキュリティと個人情報の扱い

住所入力フォームでは、郵便番号だけでも地域を推定できます。氏名、電話番号、メールアドレスと組み合わさると個人情報としての性質が強くなるため、外部APIや補完サービスへ送る値は最小限にします。

そのうえで、送信先をhttpsに限定し、レスポンスを画面へ出すときはtextContentを使うのが堅実です。APIの値をinnerHTMLへ直接入れると、想定外の文字列が混ざった場合に表示上のリスクが増えるため、住所文字列として扱う範囲を明確にするのが一般的です。

一般に、郵便番号検索だけで認証や本人確認はできません。住所の自動入力はあくまで入力支援であり、会員登録、配送、請求などの確定処理ではサーバー側の検証、ログ管理、権限管理を別に設計します。

フォーム構造を保守しやすくする考え方

これらの実装を長く使うには、郵便番号入力、住所候補取得、画面反映、エラー表示を分けて考えると保守しやすくなります。すべてを一つのイベント処理へ詰め込むと、住所欄の分割やAPI変更に弱くなるためです。

具体的には、normalizePostalCode()で郵便番号を整え、searchAddress()で住所候補を取り、renderAddress()でフォームへ反映するのが現実的です。この分け方なら、ライブラリ方式からAPI方式へ変える場合でも、画面反映部分を大きく変えずに済みます。

同様に、フォームの入力欄が増えるほど、親子関係や入れ子構造の理解も必要になります。画面の構造を整理したい場合は、HTMLとツリー構造をマスターする!初心者からプロまでわかる7つの完全ガイドが参考になると整理できます。

導入時に確認したいチェック項目

これまでの内容を実装へ落とし込む際は、入力欄、検索処理、例外処理、個人情報の扱いを同時に確認します。郵便番号から住所を自動入力できても、手入力で修正できないフォームや、通信失敗時に何も表示しないフォームでは利用者が止まりやすくなります。

そのため、公開前にはハイフンあり、ハイフンなし、全角数字、存在しない番号、通信失敗時の表示を確認するのが現実的です。自動入力された住所に対して、番地や建物名が未入力のまま送信されないよう、送信前のメッセージも整えておきますが、覚えておくと役立つでしょう。

特に押さえたいのは、自動入力を補助として扱う姿勢です。郵便番号データは住所の一部を返すものであり、配送や本人確認に必要な情報をすべて保証するものではないため、利用者確認とサーバー側検証を組み合わせます。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。