HTML フォームの送信2 分で読めます
フォーム送信後にサンクスページへリダイレクトする
フォーム送信後に訪問者を自分のサンクスページへ送る方法。303 リダイレクト、_redirect フィールド、許可されるドメイン、再読み込みの挙動を解説します。
フォームは自分自身をリダイレクトできません。送信を受け取ったサーバーが Location ヘッダー付きの 303 See Other を返し、ブラウザーがそのページを読み込みます。Ikiform では、フォームの設定で Redirect after submit を設定するか、フォームの Allowed domains にある https: の URL を持つ hidden の _redirect 入力欄を追加します。どちらもなければ、訪問者は Ikiform がホストするサンクスページに移動します。
例は、サンクスページが実際には次のステップになっているデモ依頼フォームです。訪問者に日時を選んでもらいます。そのためリダイレクト先がいつも以上に重要になり、このページの主題である「フォームが人をどこに送るかを誰が決めてよいか」という問題が生じます。
ここが違う
HTML には「送信後にここへ移動する」という属性はありません。action はデータの送り先で、その次のページはサーバーの応答しだいです。つまりリダイレクトは常に受け取る側のサーバーが決めます。そのサーバーが Ikiform なら、影響を与える方法はちょうど 2 つあり、信頼の度合いが異なります。
| Item | Redirect after submit の設定 | _redirect の hidden 入力欄 |
|---|---|---|
| 設定できる人 | ワークスペースのメンバー(ダッシュボードで) | ページの HTML を編集できる人、または訪問者のブラウザー |
| 許可される宛先 | 任意の http: または https: の URL | https: のみ、許可ドメインかそのサブドメイン |
| 範囲 | フォーム全体で 1 つ | ページごとに 1 つ(言語別やキャンペーン別) |
| 両方設定した場合 | 優先される | 無視される |
_redirect に厳しいルールがあるのは、その値が送信と一緒に届くからです。ルールがなければ、誰でもフォームの URL を送信するリンクに入れて、訪問者をフィッシングページに飛ばせてしまいます。これがオープンリダイレクトです。
- フォームの設定に Redirect after submit の URL があれば、Ikiform はそこへの 303 を返し、それ以上は見ません。
- なければ、送信に _redirect(または _next)フィールドがあり、それが許可ドメイン上の https の URL で、ポートや認証情報を含まない場合、Ikiform はそこへリダイレクトします。
- それもなければ、Ikiform はホストするサンクスページへリダイレクトします。送信が許可ドメイン上の https のページから来ていれば、そのページは元のページへのリンクを表示します。
フォーム
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="email">Work email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="company">Company</label>
<input id="company" name="company" autocomplete="organization" required />
<label for="team_size">Team size</label>
<select id="team_size" name="team_size">
<option value="1-10">1 to 10</option>
<option value="11-50">11 to 50</option>
<option value="51+">51 or more</option>
</select>
<input type="hidden" name="_redirect" value="https://example.com/demo/next-step" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Request a demo</button>
</form>フォームの Allowed domains に example.com を追加すると、これは送信され、303 を受け取って /demo/next-step に移動します。サンクスページはサイト上の普通の HTML です。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex" />
<title>Thanks, pick a time</title>
</head>
<body>
<h1>Thanks. One more step.</h1>
<p>Pick a time for your demo. You'll get a calendar invite right away.</p>
<p><a href="https://cal.example.com/acme/demo">Choose a time</a></p>
</body>
</html>noindexで検索結果に出ないようにします。Google からそこに来る人はいないはずで、アナリティクスでサンクスページが入口になっていれば、どこかがそこにリンクしている兆候です。- 再読み込みしても安全です。Ikiform が
303を返したので、ブラウザーはこのページを GET で読み込んでおり、再読み込みしても何も再送信されません。 - このページでコンバージョンを数えるなら、セッションごとに 1 回だけ数えてください。再読み込みやブックマークでも読み込まれます。本当の件数は Ikiform のダッシュボードにあります。
別のサイトへリダイレクトする
自分のページを飛ばして、cal.example.com や日程調整サービスのドメインなど、別ドメインの予約ツールへ直接送りたいとします。_redirect を使うなら、そのドメインを Allowed domains に入れる必要がありますが、このリストにはもう 1 つの役割があります。どのサイトがフォームに送信できるかを決めることです。日程調整サービスのドメインを追加すると、そのドメインのページからもフォームに送信できるようになります。
代わりにフォームの設定で Redirect after submit を使ってください。設定できるのは自分のワークスペースだけなので任意の URL を受け付け、Allowed domains には自分のサイトだけを残せます。
フォームごとに別のページ
ダッシュボードの設定はフォームごとに 1 つの URL です。1 つのフォームを、別々のサンクスページが必要な複数のページに置く場合は、設定を空にして各ページに専用の _redirect を持たせます。ドイツ語のページなら訪問者をドイツ語のサンクスページに送ります。
<input type="hidden" name="_redirect" value="https://example.com/de/demo/danke" />リダイレクトに値を付ける
_redirect のクエリ文字列は保持されるので、訪問者の選択をサンクスページに渡せます。値は submit リスナーで設定します。これはブラウザーの検証のあと、フォームがエンコードされる前に実行されます。
const form = document.querySelector("form");
const redirect = form.elements.namedItem("_redirect");
form.addEventListener("submit", () => {
const size = form.elements.namedItem("team_size").value;
const next = new URL("https://example.com/demo/next-step");
next.searchParams.set("size", size);
redirect.value = next.href;
});訪問者は /demo/next-step?size=11-50 に移動し、ページはそのチーム規模に合った予約リンクを表示できます。個人を特定しない値に限ってください。クエリ文字列はブラウザーの履歴、サーバーのログ、アナリティクスに残ります。
fetch で送信したあとのリダイレクト
fetch の呼び出しが受け取るのはリダイレクトではなく JSON なので、Ikiform のリダイレクトのルールは適用されません。応答が ok なら自分で移動してください。
const response = await fetch(form.action, {
method: "POST",
headers: { Accept: "application/json" },
body: new FormData(form),
});
const result = await response.json();
if (result.ok) location.assign("/demo/next-step");戻るボタンでフォームに戻れるようにするなら、location.replace ではなく location.assign を使います。エラーや読み込み中の状態を含む完全なハンドラーはリロードなしのガイドにあります。
動作を確認する
- フォームの Allowed domains に自分のサイトのドメインを追加し、開発中は
localhostも追加します。空のままにすると、どこからの送信も受け付けます。 - 公開中のページからフォームを送信します。アドレスバーに自分のサンクスページが表示され、Network パネルでは送信に
303が返っています。 - サンクスページで再読み込みします。ブラウザーは再送信を確認せず、ダッシュボードの送信データも 1 件のままです。
_redirectを許可されていないドメインのアドレスに変えて送信します。エラーなしで、代わりに Ikiform がホストするサンクスページに移動します。- ダッシュボードで Submissions を開きます。送ったすべてのフィールドを含む新しい送信データがあります。
ハマりどころ
| 問題 | 原因と対処 |
|---|---|
ドメインは許可されているのに _redirect が無視される | フォームの設定で Redirect after submit が設定されていて、常にそちらが優先されます。ページごとのリダイレクトを使うには設定を消してください |
本番では動くが localhost では動かない | _redirect はポートなしの https: でなければならないので、http://localhost:3000/thanks は通りません。プレビューデプロイでテストするか、ローカルではホストされたページで良しとしてください |
| ホストされたサンクスページにサイトへ戻るリンクがない | 戻るリンクが出るのは、フォームの許可ドメインにある https: のページから送信されたときだけです。ドメインを追加するか、自分のページへリダイレクトしてください |
| ブラウザーが自分のページではなく Ikiform のサンクスページに移動する | _redirect は、ドメインが Allowed domains にあり、https: の URL でないと無視されます。ドメインを追加するか、代わりにフォーム設定で Redirect after submit を設定してください。 |
| サンクスページが検索結果に表示される | ページに <meta name="robots" content="noindex"> を追加し、ナビゲーションからリンクしないでください |
通る URL と通らない URL の例を含む正確なルールは HTML フォームにあります。応答が 302 や 200 ではなく 303 である理由は概要で説明しています。
よくある質問
フォームを受け取るサーバーが、そのページへの 303 リダイレクトを返します。Ikiform では、フォームの設定で Redirect after submit を設定するか、フォームの許可ドメインにある https の URL を持つ hidden の _redirect 入力欄を追加します。
フォームの Redirect after submit が設定されていて常にそちらが優先されているか、URL がルールを満たしていないかのどちらかです。https で、許可ドメインかそのサブドメイン上にあり、ポート、ユーザー名、パスワードを含まない必要があります。許可ドメインのないフォームは _redirect を無視します。
はい。フォームの Redirect after submit の設定に URL を入れてください。任意の http か https の URL を受け付けます。代わりに _redirect を使うと、そのサイトを許可ドメインに追加することになり、そのサイトからもフォームに送信できるようになります。
Ikiform のリダイレクトではできません。URL をそのまま使うからです。submit リスナーで個人を特定しない値を _redirect の URL に付けるか、fetch で送信したあとに自分のスクリプトでメッセージを表示してください。
手順で詰まったときや、あなたの状況に合うガイドがほしいときはメールでどうぞ: hello@ikiform.com