🗳️

Cloudflare Pages Functionsでリバースプロキシーを実装する

2024/02/13に公開

Cloudflare Pages で公開しているサイトの特定ディレクトリだけ別のリポジトリのサービスを参照する必要があり、リバースプロキシーを実装して対応しました。

要件

構造としては以下のように1つのカスタムドメインのサブディレクトリに別のリポジトリのサービスを割り振りたいという要件です。

https://github.com/to-r/XXXXX -> https://xxxx.com/
https://github.com/to-r/YYYYY -> https://xxxx.com/yyyy/

Cloudflare Pagesの場合1つのプロジェクトに割り当てられるリポジトリは1つだけなのでこういったマルチリポジトリに対応させようとすると一工夫いります。

そこで今回はリバースプロキシーを利用して実装しました。

https://github.com/to-r/XXXXXに関しては通常のフローでカスタムドメインを割り振ります。

https://github.com/to-r/YYYYYに関してはカスタムドメインは割り振らずにデフォルトで割り振られるyyyy.pages.dev といったドメインを利用します

実装方法

リバースプロキシーはhttps://github.com/to-r/XXXXXfunctions/_middleware.jsに実装します。

_middleware.jsはリクエストの最初に実行され条件に応じて処理を変更することができます。

今回は https://xxxx.com/yyyy/ 以下にアクセスがある場合にhttps://yyyy.pages.dev/の内容を取得して表示を行います。

実装内容は以下のコードです。

functions/_middleware.js
const handleReverseProxy = async (context) => {
  const originalUrl = context.request.url;
  const url = new URL(originalUrl);
  // /yyyy/内でなければ処理を中断
  if (url.pathname.indexOf("/yyyy/") !== 0) {
    return await context.next();
  }
  // /yyyy/内であればhttps://yyyy.pages.devよりコンテンツを取得
  const newUrl = new URL(
    `https://yyyy.pages.dev${url.pathname.replace("/yyyy/", "/")}${url.search}`
  );
  const response = await fetch(new Request(newUrl), {
    headers: new Headers(context.request.headers),
  });
  // 取得したコンテンツをレスポンスとして返す
  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers: new Headers(response.headers),
  });
};

export const onRequest = [handleReverseProxy];

細かいディレクトリの制御などが必要な場合にはリバースプロキシーは有用なテクニックなので活用するとよいでしょう。

株式会社トゥーアール

Discussion