hoge

いわゆるWeb Developerの備忘録

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

住所を入力する際に、郵便番号を入れると町名まで自動で入力を補助してくれる機能を採用しているサイトは多くあります。

スクリプトを読み込んで、クラス名を input タグに付与するだけで簡単に使えるライブラリとして YubinBango があります。

yubinbango/yubinbango

YubinBango を使う

サイトの README にもありますが、以下のように読み込むと使えるようになります。

<script src="https://yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>
<form class="h-adr">
  <span class="p-country-name" style="display:none;">Japan</span><input type="text" class="p-postal-code" size="8" maxlength="8"><br>

    <input type="text" class="p-region p-locality p-street-address p-extended-address" /><br>
</form>

Vue と組み合わせたときの問題点

blade で書いていた時はこの方法でも良かったのですが、vue に変更した際に使えなくなってしまいました。

vue では input を v-model でバインドしているため、見かけ上自動入力されたように見えるだけで値が渡っていません。町名までしか自動入力はされないので、番地を書いた時に変数にも反映されるようになりますが、チラツキが気になったのでこの方法はやめました。

別の方法として YubinBango を実装しているコアを npm で読み込んで使うという方法があるのですが、こちらも不具合から使うことができません。

Vue.js にて郵便番号からの住所自動入力 - Qiita

本当なら npm install yubinbango-core から require などで読み込みたいのだがうまくいかず。誰か教えてください:pray_tone1:

YubinBango module が export されていない · Issue #4 · yubinbango/yubinbango-core

どうやら更新が 3 年前で止まっており、修正のためのリクエストも受け入れられていなかったので、YubinBango は使わないことにしました。

郵便番号-住所検索 API を使う

ライブラリを読み込むのではなく、Ajax を使って外部 API を使うことでも自動入力をすることができます。

郵便番号-住所検索 API

axios を使っているので、実際に Vue で使おうとすると以下のようになります。

<template>
  <form>
    <input type="text" maxlength="8" v-model="form.zipcode"><br />
    <input type="text" v-model="form.address" /><br />
  </form>
</template>

<script>
export defalut {
  data: {
    form: {}
  },
  computed: {
    zipcode() {
      return this.form.zipcode;
    }
  }
  watch: {
    async postalCode(val) {
      if (7 > val.length) {
        return;
      }
      const res = await axios.get(`https://api.zipaddress.net/?zipcode=${val}`);
      if (200 === res.data.code) {
        this.$set(this.form, "address", res.data.data.fullAddress);
      }
    }
  }
}
</script>

v-model="zipcode"でバインドされている input タグが入力を受けるたびに、watch メソッドを使ってリクエストを行います。何度もリクエストするのは負荷がかかるので、日本で使われている郵便番号の桁数(7 桁)を超える入力であった時のみリクエストします。

この方法で問題ないと思ったのですが、JavaScript で外部 API を呼び出そうとすると CORS に引っかかってしまうようです。

そのため、外部 API にアクセスするのはサーバ側(今回は Laravel)で、Ajax はサーバ側の API を叩くことで取得が可能です。

Route::get('zipcode', function (Request $request) {
    $url = "https://api.zipaddress.net/?zipcode={$request->zipcode}";
    return file_get_contents($url);
});
- const res = await axios.get(`https://api.zipaddress.net/?zipcode=${val}`);
+ const res = await axios.get(`/api/zipcode/?zipcode=${val}`);

PHP - laravel + vue + axios で OpenWeatherMapAPI から天気を取得したい| teratail

file_get_contents を使うのはあまり良くないようなので、cURL で取得したほうが良さそうです。


同じカテゴリー(Tech)の記事
上の画像に書かれている文字を入力して下さい
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

削除
郵便番号から住所を自動で入力する
    コメント(0)