JavaScript

The JavaScript requestSubmit() method asks a form to submit as if a submit button were activated, so validation, the submit event, and the chosen submitter all participate in the normal submission flow.

requestSubmit()

requestSubmit() は、フォームを「送信ボタンが押されたのと同じ流れ」で送信し、検証・submit イベント・送信ボタンごとの差まで反映させるためのAPIです。

このページでできるようになること

まずは直感:requestSubmit() って何?

ざっくり言うと、requestSubmit() は「フォームを強制送信する」ではなく、「送信ボタンが押された扱いで送信をお願いする」ためのメソッドです。

正確な定義(仕様に沿った説明)

何のために存在するか

requestSubmit() は、HTMLFormElement に対して「送信を要求する」メソッドです。submit() と違い、通常の送信ボタンを押したときに近い流れで処理されます。

何に適用されるか(対象)

対象は form 要素です。つまり const form = document.querySelector('form'); のように取得した HTMLFormElement で使います。

できること / できないこと(制約)

できること
  • 通常のフォーム送信と同じく、対話的な制約検証(interactive constraint validation)を通す
  • submit イベントを発火し、リスナー側で preventDefault() による中止ができる
  • 特定の送信ボタンを submitter として指定し、その formaction / formmethod / formenctype / formnovalidate / formtarget を反映できる
できないこと(重要)
  • 送信ボタンではない要素を submitter にすること(TypeError
  • 別フォーム所属のボタンを渡すこと(NotFoundError
  • submit() のように検証やイベントを飛ばして送ること

影響範囲(検証/イベント/送信データ)

検証
フォームが無効なら送信されず、ブラウザ標準のエラーUIが出ます。ここが submit() との最大の違いです。
イベント
submit イベントがフォーム自身で発火します。イベントオブジェクトは SubmitEvent で、submitter からどのボタン扱いだったかを取得できます。
送信データ
指定した送信ボタンに name があれば、そのボタンの情報も送信データに含まれます。<input type="image"> でも同様です。

基本の書き方(最短の型)

最小サンプル(コピペ用)

JavaScript

const form = document.querySelector('#profileForm');

form.requestSubmit();

まずは「form.requestSubmit() で通常の送信フローに乗せる」と覚えるのが最短です。

特定の送信ボタンとして送る

JavaScript

const form = document.querySelector('#postForm');
const publishButton = document.querySelector('#publishButton');

form.requestSubmit(publishButton);

送信ボタンごとに formmethodname/value が違うなら、どのボタン扱いで送るかを明示します。

最小デモ:submit() と何が違う?

下のデモは実際の送信は止めつつ、requestSubmit()submit() の違いをログで見える化したものです。

※ このデモでは画面遷移を防ぐため、submit イベント内で preventDefault() しています。


        

requestSubmit()

  • 送信ボタンを押した流れに近い
  • 検証が走る
  • submit イベントが発火する
  • preventDefault() で止められる

submit()

  • フォーム送信を直接実行する
  • 検証を通さない
  • submit イベントが発火しない
  • 送信前フックを飛ばしやすい

JavaScript

const form = document.querySelector('#compareForm');

form.addEventListener('submit', (event) => {
    event.preventDefault();
    console.log('submit event fired');
});

form.requestSubmit(); // 検証と submit イベントを通る
form.submit();        // 検証も submit イベントも通らない

仕様として押さえるポイント(初心者が事故りやすい所)

戻り値は?
requestSubmit() の戻り値は undefined です。成功/失敗を真偽値で返すAPIではありません。
引数なしだとどうなる?
フォーム自身を submitter として扱って送信を要求します。特定ボタンの form* 属性や name/value を反映したいなら、明示的にボタンを渡します。
どんな要素を渡せる?
渡せるのは「送信ボタン」だけです。典型例は <button type="submit"><input type="submit"><input type="image"> です。
別フォームのボタンを渡したら?
そのボタンの form owner が対象フォームでなければ NotFoundError になります。見た目が近くても所属フォームが違えば使えません。
formnovalidate は効く?
はい。指定した submitter に formnovalidate があれば、その送信では検証をスキップできます。つまり「下書き保存だけ検証なし」のような分岐が作れます。
submit イベントはどこで発火する?
フォーム自身です。送信ボタンではありません。どのボタンだったかは event.submitter から取得します。

submitter を使うと何がうれしい?

複数の送信ボタンを持つフォームでは、「どのボタンで送ったか」が業務ロジックの分岐になります。


        

JavaScript

form.addEventListener('submit', (event) => {
    event.preventDefault();

    console.log(event.submitter?.name);  // intent
    console.log(event.submitter?.value); // save / publish
});

form.requestSubmit(publishButton);

submit() と混同しやすいポイント

requestSubmit() = 即送信
違います。まず検証と submit イベントの流れに入ります。そこで止まることがあります。
submit() でも同じ
違います。submit() は検証も submit イベントも通しません。送信前のロジックがあるフォームでは意味が大きく変わります。
submit イベントはボタンで発火する
違います。発火先はフォームです。どのボタンかは SubmitEvent.submitter を見ます。
見た目が送信ボタンなら渡せる
違います。送信ボタンであることに加えて、そのフォームのメンバーである必要があります。

実務でよくある使用例(制作会社の現場を想定)

自作UIのクリック後に通常送信へ戻す
確認ダイアログや前処理のあとで requestSubmit() を呼べば、ブラウザ標準の検証と送信フローに戻せます。

JavaScript

const form = document.querySelector('#contactForm');
const sendButton = document.querySelector('#sendButton');
const customButton = document.querySelector('#customSend');

customButton.addEventListener('click', () => {
    const ok = window.confirm('送信しますか?');
    if (!ok) return;

    form.requestSubmit(sendButton);
});
複数ボタンの分岐を JS から明示する
保存・公開・下書きなどで挙動が違うフォームでは、どのボタン扱いで送るかを JavaScript 側で選べます。
フォーム送信の前に値を補正する
hidden 項目の更新や軽い整形をしてから requestSubmit() に渡すと、検証とイベントを壊さずに前処理を挟めます。

事故りやすい実装と回避策

事故1:form.submit() を使ってしまい、submit イベント内の Ajax 分岐や分析タグが走らない。

回避:通常の送信フローを通したいなら requestSubmit() に置き換える。

事故2:公開ボタンの formmethod="post" を効かせたいのに、引数なしの requestSubmit() を呼んでしまう。

回避:requestSubmit(publishButton) のように対象ボタンを明示する。

事故3:送信ボタンではない通常ボタンを渡して TypeError になる。

回避:type="submit" の有無とフォーム所属を確認する。

切り分けの順番:event.submitterevent.defaultPreventedform.checkValidity() → ボタンの form* 属性、の順で見ると原因を追いやすいです。

A11y / UX の観点での注意

関連APIとの相互作用

submit()
検証と submit イベントを飛ばして直接送るメソッドです。通常フローを通したいなら用途が違います。
checkValidity()
有効かどうかを真偽値で確認します。UI表示は基本的に行いません。
reportValidity()
有効でないときにブラウザのエラーUIを出しながら確認します。
SubmitEvent.submitter
submit イベント時に、どの送信ボタンが起点だったかを取り出します。

試験で得点できる整理

FAQ

requestSubmit()click() と同じ?
完全に同じではありませんが、送信ボタンを押した流れに近い送信をフォーム側から要求するAPIです。主語が「ボタン」ではなく「フォーム」です。
無効なフォームで requestSubmit() を呼ぶとどうなる?
送信されず、ブラウザ標準の検証UIが出ます(novalidateformnovalidate がなければ)。
非同期処理のあとに呼んでもいい?
はい。たとえば前処理完了後に requestSubmit() へ戻す使い方は自然です。ただし二重送信防止は別で必要です。
古いブラウザ対策は?
かなり広く使えますが、未対応環境を考慮するなら存在確認をしてからフォールバックを検討します。ただし submit() へ落とすと挙動差が出る点は理解しておきます。

症状早見

症状:submit イベントが走らない
原因候補:submit() を呼んでいる。確認:呼び出し元。解決:requestSubmit() を使う。
症状:バリデーションが出ない
原因候補:submit() / novalidate / formnovalidate。確認:フォーム属性とボタン属性。解決:通常フローへ戻す。
症状:どのボタンで送ったか取れない
原因候補:submit イベントを見ていない、または submit() で飛ばしている。確認:event.submitter。解決:requestSubmit(submitter) を使う。
症状:TypeError が出る
原因候補:送信ボタンではない要素を渡している。確認:type="submit"。解決:送信ボタンだけを渡す。
症状:NotFoundError が出る
原因候補:そのボタンが別フォーム所属。確認:button.form === form。解決:所属フォームを揃える。

まとめ:迷ったときの判断軸