SPAのOpen Graph Protocol 対応について。さらにCloudFrontを経由した場合についてのつらい話。
もう半年以上前になってしまうけど、この話題。
サーバーサイドレンダリング不要論 - Qiitab.hatena.ne.jpogp出すためにUAを見てアプリケーションサーバーに投げたりしてるけどcloudfrontでは既定でUAが書き換えられちゃうのでキャッシュヒット率落ちるのを覚悟の上でUAを通すという辛い状況。
2016/12/24 17:32
client → cloudfront → ELB → EC2(nginx → gunicorn )
という構成。
- nginxのリバースプロキシにて
/api
はgunicornにルーティング - それ以外は try_filesで /index.html を返すという設定
基本的にはこれで動く。しかしOGPが問題。この作りだとOGPの生成にはJavaScriptが動く必要があるが、twittterやFBのクローラーはJavaScriptを解釈しない。なので、nginxでUser-Agentを見てSNSのクローラーだった場合はgunicornに処理を委譲しOGPのみを描画したドキュメントを返すようにした。
if ($http_user_agent ~ "facebookexternalhit") { ・・・ proxy_pass http://127.0.0.1:8000; ・・・
ところが、User-AgentはCloudFrontの既定の設定だと"Amazon CloudFront"に書き換えられてしまい、上記の判定ができない。仕方ないので、以下のようにCloudFrontでUser-Agentヘッダを通すよう設定した。*1 これで判定は通るようになる。しかしUser-Agentを通したことでキャッシュヒット率は落ちる。うむー。SNSのクローラーがJavaScriptを動かすようになるか、CloudFrontが CloudFront-Is-Crawler-Viewer といったヘッダを用意してくれるとありがたいんだけど。
*1:ちなみに画像にあるようにCloudFront-Is-*ヘッダも使ってみたのだけど、今回の要件には使えなかった