11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NIJIBOXAdvent Calendar 2019

Day 7

Firebaseのrobots.txtをドメイン単位で振り分けてみる

Last updated at Posted at 2019-12-06

免責

  • Sparkプランの上でやったことなので、上位プランならもうちょっとスマートな方法があったかもしれません
  • firebase.jsonの設定次第ではもっとスマートな方法があったかもしれません
  • やったことのログがメインとなります

何をやったか

Firebaseで運用しているWebサイトのrobots.txtを、Firebase HostingではなくCloud Functionsを使って、ドメインごとに別の内容を配信するようにしました。

動機

自サイトをFirebaseで運用しています。 静的コンテンツの配信ならFirebase Hostingが一番楽ですが、ここを利用すると最初に次のドメインが割り当てられます。

  • {PROJECT_ID}.web.app
  • {PROJECT_ID}.firebaseapp.com

カスタムドメインを使いたい場合も割と簡単で、Firebaseのコンソール上で指示に従ってドメインを登録すれば割とあっさり運用可能になります。便利ですね。
ただ、ちょっと困ったことがあって、デフォルトのドメインを無効化出来ないっぽいです。1

すると、こんな事件が起きます。

スクリーンショット 2019-12-03 18.54.25.png

デフォルトドメインもクロールされてる...!?

動作確認込みでデフォルトドメインも使ってたとは思うのですが、これは何かカッコ悪い気がします。
というわけで、

  • カスタムドメインでは、サイトマップなどの情報を提供できるrobots.txtを配信
  • デフォルトドメインでは、せめてbot等によるクロールをしないでもらうためのrobots.txtを配信

という対応を取ることにしました。

Firebase Hostingfirebase.jsonではダメなのか?

とりあえず、現時点では以下のような理由で「なんかダメっぽい」と仮置きしています。

ホスティング環境が分断できてない

カスタムドメインもデフォルトドメインも同じホスティングコンテンツを参照するようになってます。
そのため、配置できるrobots.txtは1個だけという判断をしています。
マルチサイト?結局ドメインが増えちゃうので問題解決にならないんじゃないかなと思ってます 2

firebase.jsonは?

firebase.jsonはリクエストに対する振る舞いが結構柔軟なのですが、ドメインによる振る舞い分岐を見つけられていません。
今のところは、多分出来ないんじゃないかなという判断をしてます。

Cloud Functionsで賄う

というわけで、苦肉の策として「/robots.txtだけはCloud Functionsで配信する」という方針を取ることにしました。

実コード

index.ts
import * as functions from 'firebase-functions';

const robotsAllow = `
sitemap: https://example.com/sitemap.xml
`

const robotsDisallow = `
User-agent : *
Disallow : /
`

export const ROBOTS_TXT = functions.https.onRequest((req, res) => {
  const host = req.header('X-Forwarded-Host');
  const robotsTxt = host === 'example.com' ? robotsAllow : robotsDisallow;
  res.type('txt')
    .set('Cache-Control', 'public, max-age=7200, s-maxage=3600')
    .send(robotsTxt.trim())
    .end();
});

やったことの分割整理

複数のrobots.txtを用意する

ファイルに持たさたりするなど、いくつかパターンが有りましたが、ワンソースで雑に解決したかったので、
robotsAllowにカスタムドメイン向けのテキスト」「robotsDisallowにデフォルトドメイン向けのテキスト」と、
変数で管理するようにしました。

アクセスしてきたドメイン名でrobotsTxtを決定

Cloud FunctionのHTTPトリガー処理はリクエストヘッダーとしてX-Forwarded-Hostを受け取ります。
この中身がまさに「アクセスしてきたドメインが何か」を持っているため、この中身をベースに「どちらのrobots.txtを配信するか」を決定します。

レスポンスする

resオブジェクトを使って、粛々と中身をレスポンス。追加で次のことをしています。

  • MIMEタイプを変えるために、type() を呼び出し 3
  • 頻繁に関数を呼び出しされるのもあれなので、とりあえずCache-Controlで多少はキャッシュしてもらう
  • robotsTxtの中身は先頭と末尾に改行がいるので、trim()で整形

振り返り

リライト設定だしHostingがCDN相当の振る舞いをしてくれたりするので、ついCloud Functionsで利用しがちです。
ただ、コストを考えたほうがいいとは思いつつ、「最小限の労力で必要十分な結果を得る」にはこれぐらいの感覚で利用してよいのかなとも思いました。

  1. 無効化出来るに越したことはないので、情報募集中

  2. TODO

  3. これをしないばあいは、text/htmlになります

11
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?