エッジ判定とスクリプト連携

トラフィックを自社サイトに置いたまま、公式 PHP パック、Cloudflare Worker、または Cloudflare Pages で判定に接続。訪問者ルールに従って通過、ページ出力、同一サイトのパスを開く、リダイレクト、またはステータスのみを返します。

訪問者が自社サイトに来たとき、公式スクリプトがプラットフォームに結果を問い合わせ、通過、ページ出力、同一サイトのパスを開く、302、またはステータスのみの返却を行います。ドメインとサイトを当社側へ移す必要はありません。

公式パックは 3 種類で、判定の動作は揃えています。サイト環境に合わせて選びます:

  • PHP パック{name}-php.zip):従来のホスティング。サイトが PHP 8.3 のとき、サイトディレクトリへ置く。常に 1 パック。Apache / Nginx のリライト例は同じパック内
  • Cloudflare Worker{name}-cf-worker.zip):オリジンがすでに Cloudflare にあり、Worker ルートを付けるとき
  • Cloudflare Pages{name}-cf-pages.zip):サイトが Cloudflare Pages 上のとき。_routes.json が必須

Worker と Pages は同一 Workers ランタイムですが掛け方が異なります。コンソールは zip を 2 つに分けてダウンロードします。同じルートに Worker と Pages ミドルウェアを付けないでください。

適用シーン

  • ドメインとサイトを自社側に残したい
  • 公式スクリプトで判定に接続し、自前の API 連携を書きたくない

ホスティング配信(ドメインをプラットフォームへ向ける)も従来どおり使えます。

スクリプトの選び方

サイト環境使うもの
自社サーバーまたはレンタルで PHP 8.3{name}-php.zip
サイトがすでに Cloudflare にある(オリジン + ルート){name}-cf-worker.zip
サイトが Cloudflare Pages 上{name}-cf-pages.zip

いずれも同じ判定 API(POST /v1/decision、Bearer)を呼び出します。スクリプトは実行時に PHP バージョンを検査しません。

使い方

  1. エッジ判定を開通し、プランを確認する
  2. コンソールの「エッジ連携」でルールテンプレと、通過/遮断時の動作を設定する
  3. 環境に合わせて公式 PHP パックCloudflare Worker、または Cloudflare Pages をダウンロードする(並列、どれか一方)
  4. 下の対応する手順でデプロイする
  5. 訪問者がそのサイトを開くと、スクリプトが結果に従って実行する

シーン設定

「エッジ連携」の各シーンは、キー 1 本、ルールテンプレ 1 件、動作一式に対応します。

フィールド説明
name1–128 文字シーン名
rule_template_id必須アカウント内で見える広告ルールテンプレ(国、UA、IP など)
pass_actionallow / html / redirect / pathルール通過時の動作
pass_filehtml のとき必須ファイル名のみ。例 land.html
pass_urlredirect のとき必須http/https、または / で始まるサイト内パス
pass_pathpath のとき必須/ で始まるサイト内パス
fail_actionhtml / redirect / path / denyルール不通過時の動作
fail_filehtml のとき必須。既定 safe.htmlファイル名のみ
fail_urlredirect のとき必須pass_url と同じ
fail_pathpath のとき必須pass_path と同じ
deny_status403 / 404 / 204 / 410。既定 404deny のみ
append_query0 / 1。既定 1redirectpath で現在のクエリを付けるか
fail_modehtml / allow。既定 html通信失敗や JSON を読めないとき:セーフページまたは LP
statusnormal / disabled。既定 normaldisabled のとき判定 API は 403

ファイル名・URL・パスの制約:

  • HTML ファイル名^[A-Za-z0-9._-]+\.html$、最大 128。../\ は不可
  • リダイレクト先:最大 1024。host 付きの http/https、または / で始まるサイト内パス。//evil.com..、バックスラッシュは不可
  • サイト内パス:最大 1024。/ で始める。..//http、バックスラッシュ、空白は不可。? 以降のクエリは可

通過/遮断の動作は保存後すぐに効きます。キー、シーン ID、fail_mode、パック内の既定 HTML ファイル名はスクリプト定数です。これらを変えたら再ダウンロードして上書きしてください。

作成またはローテーション後、PHP パック、Cloudflare Worker、Cloudflare Pages はいつでもダウンロードできます(Peek で ZIP に入れ、同じキーを繰り返し取得可能)。正式キーはローテーション時だけ変わります。ローテーションまたはシーン削除後、旧キーは直ちに無効になるため、再ダウンロードして上書きしてください。

判定リクエスト

公式スクリプトは次を送ります:

POST /v1/decision
Authorization: Bearer <シーンのキー>
Content-Type: application/json
Accept: application/json

パックのタイムアウトは 2500 ms。本文:

フィールド必須制約スクリプトの取り方
ipはい有効な IPv4 / IPv6CF-Connecting-IPX-Real-IPX-Forwarded-For の先頭 → REMOTE_ADDR
uaはい非空、最大 1024User-Agent
refererいいえ最大 2048Referer
languageいいえ最大 256Accept-Language
urlはい最大 4096。scheme と host が必要現在の完全な URL(クエリ含む)
scene_idはい正の整数。キーのシーンと一致必須ダウンロード時に定数へ書き込む
{
  "ip": "203.0.113.10",
  "ua": "Mozilla/5.0 ...",
  "referer": "https://example.com/",
  "language": "ja,en;q=0.8",
  "url": "https://yoursite.com/",
  "scene_id": 12
}

scene_id がキーと一致しない、またはシーンが停止中のときは 403 です。国、ASN、プロキシなどはプラットフォームが ip などから計算します。スクリプトはお客様側で第三者 IP データベースを呼びません。

判定レスポンス

成功時は HTTP 200

{
  "code": 200,
  "msg": "SUCCESS",
  "data": { "action": "allow" }
}

dataaction によって変わります:

actionその他の dataスクリプトの動作
allow(なし)LP を出す。PHP / Cloudflare はパック内 ALLOW_HTML_FILE(既定 land.html
htmlpagelanding(通過)または safe(遮断);file:HTML ファイル名そのファイルを出す
redirecturlappend_query(真偽)http/https またはサイト内パスへ 302
pathpathappend_query(真偽)同一サイトのパスを開く(アドレスバーは変わらない)
denystatus403 / 404 / 204 / 410その HTTP ステータスのみ。本文なし

code200 でない、通信失敗、または JSON を読めないときは、シーンの fail_modehtml はセーフページ、allow は LP)になります。スクリプトの応答は Cache-Control: no-store です。

公開判定のよくある失敗(公式スクリプトはすべてフォールバックし、訪問者にはこれらのコードを出しません):

HTTP意味
401キー欠落または無効
403未開通、シーン停止、scene_id 不一致、またはアカウント利用不可
400リクエスト項目が不正、またはルールテンプレが無効
429当日の回数切れ
503プラットフォームが一時不通

PHP と Cloudflare

同じ action は揃えます。実装は実行環境に従います:

actionPHP(PHP 8.3Cloudflare
html / allowindex.php と同じディレクトリのファイルを読むローカルディスクはないため、そのファイル名を同一オリジン GET
pathドキュメントルート内を includerealpath はドキュメントルート内同一オリジンのパスを fetch して本文を返す
redirectどちらも 302。append_query は既定オン同左
deny対応する HTTP ステータス同左

path/ で始める必要があります。..//http、バックスラッシュは不可。リダイレクトに //evil.com は使えません。

コンソールでの設定

  1. 開通後、「エッジ連携」を開く
  2. 上の項目でシーンを設定する
  3. 公式 PHP パック、Cloudflare Worker、または Cloudflare Pages をダウンロードする
  4. 「判定記録」で成功・失敗を確認できる。シーン / 通過 / アクション / IP で絞り込み

ページ上部に本日の使用/残量が表示され、日次回数はプランに従います。

PHP パック

サイト側は PHP 8.3 からプラットフォームへ HTTPS で届ければ足ります。パックは実行時に PHP バージョンを検査しません。公式 PHP は常に 1 パック({name}-php.zip)です。ファイルをサイトディレクトリへ置き、実ファイル以外は index.php へ向けます。

  1. 公式 PHP パックをダウンロードして解凍する
  2. サイトディレクトリへ置く(index.php とページファイルを同じ階層に)
  3. パック内の .htaccess または nginx.conf.example で、実ファイル以外を index.php へ向ける。サイトルート /index.php へ入ること。同じ階層に index.html があると / が静的トップになり、判定を通らないことがある
  4. プレースホルダを実 HTML に差し替え、ファイル名はコンソールと一致させる

パックの中身:index.php(https の判定口、キー、シーン定数済み)、シーンのファイル名に合わせたプレースホルダ HTML、README.txt.htaccessnginx.conf.example。実ファイル(拡張子付きの静的ファイルを含む)は判定を通さずそのまま出します。LP はスクリプトが出力してください。/land.html を直接開いてルールを走らせないでください。

Cloudflare Worker

オリジンがすでに Cloudflare にあり、Worker ルートを付けるときは {name}-cf-worker.zip をダウンロードします。Pages と同一ランタイムで、収集と動作も同じです。まず CF-Connecting-IP、続けて UA、Referer、Accept-Language、完全な URL を付け、Bearer で判定 API を呼びます。Node の fs は使いません。html / path は同一オリジンからファイルを取得します。拡張子付きの静的ファイルは判定を通さずそのまま出します。

パックの中身:

  • worker.js
  • wrangler.toml.example
  • README.txt
  • シーンのファイル名に合わせたプレースホルダ HTML

functions/_routes.json は含みません。Pages ミドルウェアと同じルートに付けないでください。

  1. コンソールから Cloudflare Worker をダウンロードする
  2. land.html / safe.html(またはシーンで設定したファイル名)を同一オリジンで GET できる場所へ置く
  3. README に従い wrangler.toml.examplewrangler.toml に変え、アカウントとルートを記入する
  4. wrangler でデプロイし、Worker をサイトのルートに紐付ける

html は同一オリジンからファイルを取得します(fetch(new URL('/' + file, request.url)))。これらのファイルがオリジンで届くことを確認してください。

Cloudflare Pages

サイトが Cloudflare Pages 上のときは {name}-cf-pages.zip をダウンロードします。functions/_middleware.js を使います(Pages Functions、Worker と同じランタイム)。公式の置き方はサイト全体のミドルウェアでサイトルートを扱います。/go のような入れ子パスだけの試験配置とは異なります。Worker と同じルートに付けないでください。

パックの中身:

  • functions/_middleware.js
  • _routes.json(Pages では必須)
  • README.txt
  • シーンのファイル名に合わせたプレースホルダ HTML
  1. functions/_middleware.js を Pages プロジェクトの functions/ ディレクトリへ置く
  2. _routes.json を Pages プロジェクトのルートへ置く(functions と同じ階層)。静的出力が public/ の場合(Astro / Vite など)は public/_routes.json にし、公開ルートに含まれるようにする。Pages では _routes.json必須
  3. land.html / safe.html(またはシーンのファイル名)をサイトルートへ置く(functions と同じ階層)。Functions と同じ URL 接頭辞の下に置かない(例:functions/go と静的 /go/*.html)。Pages が Functions を自動除外し、ミドルウェアが動きません
  4. 既に functions/_middleware.js がある場合(言語リダイレクト、地域ブロックなど)、公式ファイルで丸ごと上書きしない。判定ロジックをマージするか、別パスに載せる。_routes.jsoninclude /* は残す
  5. Pages の手順で公開する

Pages にローカルディスクはありません。html / path の同一オリジン GET は、Pages の ASSETS を優先し、なければ同一オリジン fetch に内部ヘッダを付けて、判定へ再入しないようにします。

回数

成功した公開判定だけ当日分に計上します。枠はプラットフォーム側で集計します。枠切れや一時不通のときはフォールバックになります。

よくあるつまずき

現象確認
「エッジ連携」が見えない開通済みか、管理者アカウントか
キーを替える、または漏洩を疑うローテーションし、再ダウンロードして上書き
アップロード後ずっとセーフページルールの想定、プレースホルダ差し替え、ファイル名の一致
サイトルート / で判定が走らず静的トップのままindex.php へのリライトがあるか。同じ階層の index.html がトップを奪っていないか
Worker / Pages がずっとセーフページ、または html が出ない同一オリジンのファイルを GET できるか、ルートがスクリプトに届いているか。Pages では HTML がサイトルートにあり、_routes.json があるか
Pages ミドルウェアが動かない公開ルートに _routes.jsoninclude /*)があるか。LP の HTML が Functions と同じ接頭辞で自動除外されていないか。既存のルート _middleware が公式ファイルを丸ごと上書きしていないか
path が出ないPHP:ドキュメントルート内か、index.php へのリライトか。Cloudflare:同一オリジンのパスを GET できるか
プラットフォーム不通なのに LP が出るフォールバックが通過側(リスクあり)

関連:コンソール概要 · ルールテンプレート · よくある質問