背景
vue.jsの勉強をしていて、郵便番号検索APIを使ったところ、CORSが発生してうまく表示できなかった。
開発中のことなので、楽にCORSが回避できないか方法を探ったところ、proxyを使うと良いという記事を見つけた。
早速やってみたものの、コンソールに出たエラーが示すURLが変わらず、解決まで意外と時間がかかったので、メモを残すことにした。
ちなみに、郵便番号検索には、zipcloudを利用した。
問題点
郵便番号検索APIのURLとローカル開発中のURLは別物で、originが違うので怒られる。
開発中のもの http://localhost:8080
郵便番号検索 https://zipcloud.ibsnet.co.jp/
これはポートを違えても同様なので、ローカルでフロントエンドとバックエンドを別々に開発している場合にも発生する。
これを開発環境側を変更せずに解決したい。
proxyの設定と問題発生
proxyの設定は、プロジェクトルートに配置するvue.config.jsに行う。
vue/cli 4.5.8で作ったプロジェクトにはそれがなかったので、追加して中身を記述する。
ここでの目的は、ローカル開発環境からhttp://localhost:8080/postal
にアクセスしたら、郵便番号検索バックエンドのURLに変えてアクセスすることだ。
module.exports = {
devServer: {
port: 8080,
proxy: {
'/postal': {
target: "https://zipcloud.ibsnet.co.jp/api",
changeOrigin: true,
}
}
}
};
APIを実行する側は以下の通り。
axios
.get("/postal/1234567")
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log("エラー発生");
console.log(err);
});
機体としてはhttps://zipcloud.ibsnet.co.jp/api/postal/1234567
になって、見つからないというようになるのかな、と思ってましたが、実際に表示されたエラーはhttp://localhost:8080/postal/1234567
でproxyされてないっぽい。
GET http://localhost:8080/postal/1234567 404 (Not Found)
解決方法
解決方法と言って良いか迷うところだが、ここでの問題点はproxyで変わった結果のurlでエラーが表示されていなかったということだ。
期待したエラーは以下のようなものだが、実際は上記のようになっていた。
GET https://zipcloud.ibsnet.co.jp/api/postal/1234567 404 (Not Found)
zipcloudの郵便番号検索APIをご覧いただければわかるが、targetのurlはapiで止まらず、その続きがある。パラメータも必要だ。これらがないので、Not Foundになる。ここまでは予想していた。ただエラーの出方が期待と違っていた、というわけだ。
targetのurlが存在しないものになってしまうような設定になってしまうと、proxyが働いてないじゃないか、みたいに悩まされた。
結果としては、以下のようになっていると、やりたいことが実現できた。
module.exports = {
runtimeCompiler: true,
devServer: {
port: 8080,
proxy: {
'/postal': {
target: "https://zipcloud.ibsnet.co.jp/api/search",
changeOrigin: true,
pathRewrite: p => {
console.log(p);
r = p.replace(/^\/postal\/*/, '?zipcode=');
console.log("result:" + r);
return r;
},
}
}
}
};