クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Express】GitHub PagesからHerokuのPostgreSQLへCRUD操作(CORSエラー対策も)

Expressの続きです。前回はbody-parserでフォームからHerokuのPostgreSQLにCRUD操作しました。今回はGitHub PagesからCRUD操作します。別ドメインの問題でCORSエラーになったため、Expressのcorsモジュールでアクセス許可の設定もしました。それではいきましょう!

【目次】

※参考:前回記事
【Express】body-parserでフォームからHerokuのPostgreSQLにCRUD(後編) - クモのようにコツコツと

※参考:Node.js / Expressを習得するためにやったことまとめ
qiita.com

前回のおさらい

body-parserでフォームからHerokuのPostgreSQLにCRUD操作 f:id:idr_zz:20201106074440j:plain

詳細は下記の記事を参照。

※参考:【Express】body-parserでフォームからHerokuのPostgreSQLにCRUD(後編) - クモのようにコツコツと

GitHubにはリポジトリ の静的なページを表示する「GitHub Pages」がある。そこからもPostgreSQLにCRUD操作できるか確かめたい。

GitHub Pagesを設定

GitHub Pagesを設定する。下記の手順にて。

※参考:GitHubとSourcetreeでGitHub Pagesとローカルファイルを同期させる - クモのようにコツコツと

GitHubリポジトリ

※参考:GitHub - ryo-i/Express-Heroku-Test

GitHub Pages(直下はReadMeが表示されている)

※参考:【Express】body-parserでフォームからHerokuのPostgreSQLにCRUD(前編) | Express-Heroku-Test

GitHub Pagesからは404、405エラーに

前回作成した「今日の一句」ページは「/public」ディレクトリの下層にある。

f:id:idr_zz:20201115161952j:plain

※参考:ExpressでHerokuのPstgreSQLとbody-parser連携

ページ読み込み時にFetch APIでPostgreSQLのテーブルを読み込む設定だが、Dev-toolsのNetworkを見ると404エラーになっている。 f:id:idr_zz:20201115162031j:plain


あたらしい一句を詠んでみるが、「送信」ボタンを押しても反映されない。 f:id:idr_zz:20201115163133j:plain

Networkを見ると今度は405エラーになっている。 f:id:idr_zz:20201115163244j:plain


まあそりゃそうだよな、と思う。

リクエストURLは相対パス/fetchなのでHerokuではなくGitHub Pagesにアクセスしている。

Request URL: https://ryo-i.github.io/fetch

GitHub Pagesは静的なページしか生成しないため、APIのような動きはしない。

ステータスコード404、405の詳細はこちら

※参考:HTTP レスポンスステータスコード - HTTP | MDN

URLを絶対パスに変更→CORSエラーに!

では、リクエストのURLを相対パスではなくHerokuの絶対パスにしたらどうなるだろう。

「fetch_crud.html」を複製して「fetch_crud_github.html」を作成

jsのリンクを「fetch_crud.js」から「fetch_crud_github.js」に変更

<script src="js/fetch_crud_github.js"></script>

「fetch_crud.js」を複製して「fetch_crud_github.js」を作成

Fetch APIのリンク先をフルパスに変更

const url = 'https://aqueous-mountain-80366.herokuapp.com/fetch';

変更内容をGitHubにコミット。下記の3つのコマンド

$ git add .
git commit -m "ReadMe修正、GitHub用ページ作成 他"
git push -u origin main

修正が反映された! f:id:idr_zz:20201115172254j:plain

※参考:ReadMe修正、GitHub用ページ作成 他 · ryo-i/Express-Heroku-Test@a77463d · GitHub


ページを開くと今度はCORSエラーになった! f:id:idr_zz:20201114192639j:plain

CORSエラーとは別ドメイン間のデータのやり取りをブラウザがブロックするセキュリティ上の対策。

※参考:オリジン間リソース共有 (CORS) - HTTP | MDN

なるほど、確かに別ドメインからのアクセスはブロックしないとどこの誰からでもデータを改変できちゃうからな。

ExpressにCORSをインストール

「cors」というモジュールを使うとCORS設定ができるようだ。

※参考:cors - npm

Expressのドキュメント

※参考:Express cors middleware

その他、参考にさせていただいた記事

※参考:なんとなく CORS がわかる...はもう終わりにする。 - Qiita

※参考:heroku×node.jsでcorsエラーがなかなか解決しないときに気をつけること - Qiita

※参考:express.jsのcors対応 - Qiita


corsインストール

$ npm install cors

package.jsonを確認。corsが追加されている!

  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "ejs": "^2.7.4",
    "express": "^4.17.1",
    "pg": "^8.4.1"
  },

index.jsでCORS設定

Epxressの設定をしているindex.jsを修正する。

まずcorsモジュールをインポートする。

const cors = require('cors');

CORSのURLを設定する。

// CORS設定
const corsOptions = {
  origin: 'https://ryo-i.github.io'
}

この連想配列をcorsのオプション設定として使う。

app.use()corsを反映

app.use(express.static(path.join(__dirname, 'public')), cors(corsOptions))
  • app.ure()の引数にcors()を追加(引数をcorsOptionsに)

cors()の引数にcorsOptionsを入れるとオプション設定になる。オプションなしだと全てのアクセスのCORSを許可すると思うので、特定のドメイン(GitHub Pages)だけ許可にする設定にした。


修正をGitHubにコミットする。下記の3つのコマンド

$ git add .
git commit -m "CORS設定を追加"
git push -u origin main

修正が反映された! f:id:idr_zz:20201115171811j:plain

※参考:CORS設定を追加 · ryo-i/Express-Heroku-Test@1d4b857 · GitHub

動作確認

GitHub Pages版のページでCRUD操作してみる。

データの追加(Create)、読み込み(Read)

まずはデータの追加を行う。

ページを開いて f:id:idr_zz:20201115172515j:plain

一句「GitHub Pageで一句 詠んでみる」 f:id:idr_zz:20201115172519j:plain

「送信」ボタンを押すと一句一覧に追加された! f:id:idr_zz:20201115172522j:plain

CRUDのCreate(追加)、Read(読み込み)が実行された!


Dev-ToolsのNetwork、Headers情報を確認 f:id:idr_zz:20201115172525j:plain 先ほど「fetch_crud_github.js」で設定したHerokuのURLになっていて、結果は成功(200)

Responseを見ると先ほど送信した一句がちゃんと返ってきている。 f:id:idr_zz:20201115172529j:plain

データの修正(Upadte)

次にデータを修正(Upadte)する。

修正用にもう一句追加「ボボボーボ ボーボボボーボ ボボボーボ」 f:id:idr_zz:20201115172532j:plain

「送信」ボタンで一句一覧に追加される。 f:id:idr_zz:20201115172535j:plain

「修正」ボタンを押すと修正欄が表示される。 f:id:idr_zz:20201115172538j:plain

上の句を「ポポポーポ」に修正する。 f:id:idr_zz:20201115172543j:plain

「送信」ボタンを押すと修正が反映された! f:id:idr_zz:20201115172546j:plain

CRUDのUpdate(修正)が成功した。

データの削除(Delete)

最後、データの削除を(Delete)してみる。

先ほど追加した「ポポポーポ〜」の「削除」ボタンを押すと f:id:idr_zz:20201115172546j:plain

「ポポポーポ〜」の句が削除された! f:id:idr_zz:20201115172549j:plain

Heroku版ページとの同期を確認

Heroku版のページを開いて確認する。

おお、先ほどGitHub Pagesで追加した一句が一覧に表示されている! f:id:idr_zz:20201115174543j:plain

※参考:ExpressでHerokuのPstgreSQLとbody-parser連携(GitHub)

一句「こちらはね Herokuアプリで 詠んでるよ」を入力 f:id:idr_zz:20201115174548j:plain

「送信」ボタンを押すと一句が追加された! f:id:idr_zz:20201115174551j:plain

再びGitHub Pages版のページを開いてみると…

f:id:idr_zz:20201115172555j:plain

おお!Herokuで追加した一句がこちらでも表示された!!

※参考:ExpressでHerokuのPstgreSQLとbody-parser連携(GitHub)

最後に

ということで、GitHub PagesからHerokuのPostgreSQLにCRUD操作することができました!

Fetch APIで普通にアクセスすると別ドメイン問題でCORSエラーになりましたがExpress側でGitHub PagesのURLからのアクセスを許可したらアクセス成功しました♪

自分はフロントエンド側の実装がメインで、テスト環境などのドメインが異なる環境からAPIを叩くとよくCORSエラーになります。

そんなときはバックエンドの方に「CORSエラーになったのでアクセスを許可してください」と相談していました。今回の経験でサーバ側でどのような設定をしているのかイメージできました。

それではまた!


※参考:Node.js / Expressを習得するためにやったことまとめ
qiita.com