Cloudflare Pages Functionsでリバースプロキシーを実装する
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/XXXXX
のfunctions/_middleware.js
に実装します。
_middleware.js
はリクエストの最初に実行され条件に応じて処理を変更することができます。
今回は https://xxxx.com/yyyy/
以下にアクセスがある場合にhttps://yyyy.pages.dev/
の内容を取得して表示を行います。
実装内容は以下のコードです。
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