2020-08-30 12:16:05
CORSを許可して JavaScript で Elixir Phoenix から自分のブログ情報を取得する
CORSを許可して JavaScript で Elixir Phoenix から自分のブログ情報を取得する
そもそも
CORS は "Cross-Origin Resource Sharing" の略です。マイクロサービスを調べたりすると出くわす単語でした。よく、「サーバーサイドは Go lang でクライアントサイドは Vue で実装」みたいな言葉を見ます。指定したクライアントのみがサーバーサイドの情報を取得するために CORS を許可する必要があります。
やったこと
https://www.nao000.com/api/blogs/ で取得できるブログ情報を https://app.netlify.com/ でホスティングする静的サイトで取得して画面に表示することをやりました。ローカルでも取得できます。
GETリクエストでブログ情報を取得
https://www.nao000.com/api/blogs/ にGETリクエストすると以下のようにブログ情報が取得できるようにします。
{"blog_json":"[{"url_title":"elixir-phoenix-layout-in-layout","updated_at":null,"title":"elixir phoenix Layoutの中でLayoutを出力する","thumbnail_url_path":"","summary":"elixir phoenix Layoutの中でLayoutを出力する","pv":null,"keywords":null,
~省略~
別で静的サイトを用意する
以下が別で用意した静的サイトのプロジェクトです。単純なHTMLを表示するだけです。
__
|_ index.html
|_ js
|_ index.js
JavaScript で取得する
これを JavaScript で取得するときは以下のようにします。
(async () => {
// ブログ情報を取得
const blogJson = await fetch('https://www.nao000.com/api/blogs/')
.then(response => response.json())
.then(data => data);
// シリアライズされたブログ情報をデシリアライズする
const blogObj = await JSON.parse(blogJson.blog_json);
// 取得したブログ情報を画面表示
for (let [key, value] of Object.entries(blogObj)) {
const node = document.createElement("li");
const textnode = document.createTextNode(value.title);
node.appendChild(textnode);
document.getElementById("blogList").appendChild(node);
}
})();
HTML に表示したい
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<ul id="blogList"></ul>
<script src="./js/index.js"></script>
</body>
</html>
このままだとブラウザでエラーになります
Chromeブラウザ(バージョン: 84.0.4147.135)ですと、以下のようなエラーがコンソールに表示されました。
Access to fetch at 'https://www.nao000.com/api/blogs/' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
サーバーサイド側でCORS許可する
cors_plug を https://github.com/mschae/cors_plug に従ってインストールします。
router.ex を修正します。
pipeline :api do
plug :accepts, ["json"]
plug CORSPlug
end
# ~~~~
scope "/api", Nao000dotcomWeb do
pipe_through :api
get "/blogs/", User.SampleController, :index
end
HTMLで表示できるようになる
さきほど表示できなかった画面が表示できるようになりました。画像はローカルディレクトリをそのまま表示していますが、このプロジェクトをそのままNetlifyにデプロイしても同じ様にブログ情報を取得することが出来ます。
終わり
CORS を許可する経験というと大袈裟かもですが、業務では一切経験していませんでした。マイクロサービスを個人的に調べてるときに見かけた単語で、なんとなく概要は知っていました。実際に手を動かしてみると経験値が積まれた感覚になれました。
参考資料
- https://github.com/mschae/cors_plug
- https://medium.com/@yagoazedias/how-to-configure-cors-in-your-phoenix-application-5ef0234bc25f
- https://developer.cybozu.io/hc/ja/community/posts/900001423246-PromiseValue%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
- https://www.atmarkit.co.jp/ait/articles/1607/27/news025.html
- https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch
- https://qiita.com/techno-tanoC/items/a5f7b1f11b5f04fc2175
- https://blog.emattsan.org/entry/2018/09/24/203348
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of
- https://coliss.com/articles/build-websites/operation/work/cs-visualized-cors.html