2026年10月7日
2026年10月7日
WordPressでPOST送信が効かないときの原因と確認手順|フォーム・投稿保存・アップロード
WordPress で「フォームを送っても何も起きない」「投稿を保存できない」「送信すると白い画面や 403 になる」といった症状は、POST リクエストがサーバーまで届いていないか、届いても途中で中身が捨てられているときに起こります。原因はいくつかに分かれますが、最初にブラウザで応答を見れば、多くの場合どこで止まっているかを絞り込めます。この記事では、その確認の順番と、原因ごとの直し方を説明します(2026年10月時点の WordPress と PHP の仕様に基づきます)。
よくある症状
- お問い合わせフォームの送信ボタンを押しても、くるくる回ったまま終わらない、またはエラーが出る
- ブロックエディターで「更新」を押すと「Updating failed. The response is not a valid JSON response.」(日本語表示では、更新に失敗し、返答が正しい JSON ではないという趣旨のメッセージ)が出る
- 設定画面やメニュー画面で「変更を保存」を押すと、入力が一部だけ保存される、または何も保存されない
- テーマやプラグインの zip をアップロードすると「The link you followed has expired.」(日本語表示では、リンクの有効期限が切れているという趣旨のメッセージ)が出る
- 送信すると 403 Forbidden、413 Request Entity Too Large、500 Internal Server Error になる
まず開発者ツールで応答コードを見る
ブラウザの開発者ツール(Chrome・Edge・Firefox では F12)を開き、「Network(ネットワーク)」タブを表示した状態で、もう一度送信します。一覧から送信した瞬間のリクエスト(Method が POST のもの)を選び、Status(ステータスコード)を確認します。
| 応答 | 考えられる原因 | 見る場所 |
|---|---|---|
| 403 | WAF(ModSecurity、サーバー会社の WAF、Cloudflare など)やセキュリティプラグインが遮断した | WAF のログ、サーバー会社の管理画面 |
| 413 | 送信サイズが Web サーバーの上限を超えた | Nginx の client_max_body_size、Apache の LimitRequestBody |
| 500 | PHP の致命的エラー、または .htaccess の書き方の誤り | PHP のエラーログ、wp-content/debug.log |
| 301 / 302 の後に GET | URL の違い(http と https、www の有無、末尾スラッシュ)でリダイレクトされ、POST が GET に変わった | 送信先 URL とサイトアドレス |
| 200 だが保存されない | post_max_size や max_input_vars を超えて中身が捨てられた、nonce の確認に失敗した |
PHP のエラーログ、応答の本文 |
| リクエスト自体が出ていない | JavaScript のエラーで送信処理が動いていない | 開発者ツールの「Console(コンソール)」 |
Contact Form 7 のように REST API(/wp-json/ で始まる URL)を使って送信するフォームや、ブロックエディターの保存では、POST の宛先が /wp-json/ になります。その URL が 403 や 404 なら、REST API がセキュリティプラグインや WAF で止められていないかを確認します。
エラーを記録する設定にする
応答コードだけで原因が分からない場合は、WordPress のデバッグログを有効にします。wp-config.php の「編集が必要なのはここまで」の行より上に、次の設定を書きます(同じ定数がすでにあれば値を変えます)。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true ); // wp-content/debug.log に記録する
define( 'WP_DEBUG_DISPLAY', false ); // 画面には表示しない
もう一度送信してから wp-content/debug.log と、サーバー会社の管理画面で見られる PHP のエラーログを確認します。原因が分かったら、WP_DEBUG を false に戻します。debug.log は外から読める場所にできるため、残したままにしないでください。
原因1: 送信サイズが PHP の上限を超えている
PHP は、送られてきたデータが post_max_size を超えると、エラーを返さずに中身を捨てます。WordPress から見ると $_POST と $_FILES が空になるため、「何も起きない」「リンクの有効期限が切れている」という表示になります。PHP のエラーログには、POST Content-Length of ... bytes exceeds the limit of ... bytes という警告が残ります。
関係する設定は次の3つです。
| 設定 | 意味 | 関係 |
|---|---|---|
upload_max_filesize |
1ファイルあたりの上限 | 送るファイルより大きくする |
post_max_size |
1回の送信全体の上限 | upload_max_filesize より大きくする |
memory_limit |
PHP が使えるメモリの上限 | post_max_size 以上にしておく |
今の値を確かめる
管理画面の「ツール」→「サイトヘルス」→「情報」タブを開き、「サーバー」の項目を見ると、Web サーバーで動いている PHP の upload_max_filesize・post_max_size・max_input_vars などの値が分かります。シェルで php -i を実行すると CLI 用の設定が表示されるため、Web 側の値とは違うことがある点に注意してください。
値を変える
post_max_size と upload_max_filesize は、PHP の仕様上、実行中に ini_set() で変えられない設定です。wp-config.php に @ini_set( 'post_max_size', '128M' ); と書いても効きません。サーバーの種類に合わせて、次のどれかで変えます。
- 共用のレンタルサーバー: サーバー会社の管理画面にある「php.ini 設定」などの画面で変えます。
- VPS で PHP-FPM を使っている: php.ini を編集し、PHP-FPM を再起動します。php.ini の場所は
php --iniで確認できます(例: Ubuntu の PHP 8.3 なら/etc/php/8.3/fpm/php.ini)。
upload_max_filesize = 64M
post_max_size = 72M
memory_limit = 256M
# Ubuntu の PHP 8.3 の例。サービス名はバージョンに合わせる
sudo systemctl restart php8.3-fpm
- php.ini を編集できないが、サイトのフォルダーにファイルを置ける(PHP-FPM / CGI): WordPress のフォルダーに
.user.iniを置き、上と同じ3行を書きます。反映まで最大5分ほどかかります(user_ini.cache_ttlの既定値が300秒のため)。 - Apache の mod_php で動いている: .htaccess に
php_value post_max_size 72Mのように書けます。PHP-FPM で動いているサーバーでphp_valueを書くと 500 エラーになるため、どちらで動いているかを確かめてから使います。
Web サーバー側の上限(413 が出る場合)
413 が出るときは、PHP より手前の Web サーバーが止めています。Nginx は client_max_body_size の既定値が 1MB のため、大きなファイルを送るなら server ブロックなどで上限を上げ、設定を再読み込みします。
client_max_body_size 72m;
sudo nginx -t && sudo systemctl reload nginx
Apache では LimitRequestBody が小さく設定されていないかを確認します。
原因2: 入力欄の数が max_input_vars を超えている
項目の多いメニュー画面、WooCommerce の商品バリエーション、オプション項目の多いテーマ設定などで、「保存すると後ろのほうの項目だけ消える」場合は、PHP の max_input_vars(既定値は 1000)を超えている可能性があります。PHP は上限を超えた分の入力を捨て、エラーログに Input variables exceeded 1000 という警告を残します。
max_input_vars も ini_set() では変えられないため、上の post_max_size と同じ方法(管理画面、php.ini、.user.ini)で値を上げます。
max_input_vars = 3000
原因3: WAF やセキュリティプラグインが遮断している
送信内容に <script> や SQL に似た文字列、長い URL などが含まれていると、WAF が攻撃と判断して 403 を返すことがあります。記事にコードを載せて保存したとき、特定の文章を含むフォームを送ったときだけ失敗するなら、この可能性が高いです。
- サーバー会社の WAF: 管理画面の WAF のログで、遮断された時刻・URL を確認し、該当するルールや自分の IP の除外を設定します。一時的に WAF を止めて保存できるかを試す方法もありますが、作業後は元に戻します。
- Cloudflare などの CDN: ファイアウォールのイベントログで、遮断の記録を確認します。
- セキュリティプラグイン: プラグインのログを確認し、REST API(
/wp-json/)やadmin-ajax.phpへの POST を止める設定になっていないかを見ます。
原因4: リダイレクトで POST が GET に変わっている
フォームの送信先が http:// のままで、サーバーが https:// へ 301 や 302 でリダイレクトすると、ブラウザはリダイレクト先を GET で開き直すため、送信した内容は失われます。www の有無や末尾のスラッシュの違いによるリダイレクトでも同じことが起こります。
開発者ツールで POST の応答が 301 / 302 になっていたら、次を確認します。
- 「設定」→「一般」の「WordPress アドレス (URL)」と「サイトアドレス (URL)」が、実際に開いている URL(https、www の有無)と一致しているか
- 自作フォームやテーマの
action属性に、古い URL や相対パスの誤りが残っていないか
原因5: nonce の確認やキャッシュで失敗している
WordPress の管理画面やプラグインのフォームは、nonce(不正な送信を防ぐための一時的な値)を一緒に送り、受け取った側で確認します。nonce の有効期間は既定で最長24時間です。次のような場合に確認が失敗し、送信が受け付けられません。
- 画面を長時間開いたままにしてから送信した: ページを再読み込みしてから送り直します。
- フォームのあるページがページキャッシュに残り、古い nonce が配られている: キャッシュプラグインや CDN の設定で、フォームのあるページをキャッシュの対象から外すか、キャッシュを消してから確認します。
- ログインしたままキャッシュされたページを見ている: ログイン中のユーザーにはキャッシュを返さない設定になっているかを確認します。
自作のフォームで check_admin_referer() や wp_verify_nonce() を使っている場合は、フォーム側で wp_nonce_field() に渡した名前と、確認側の名前が一致しているかも確かめます。
原因6: JavaScript のエラーで送信処理が動いていない
開発者ツールの Network タブに POST のリクエストが出ていないなら、ブラウザ側で止まっています。「Console」タブに赤いエラーが出ていないかを確認します。よくあるのは、次のような場合です。
- 別のプラグインやテーマのスクリプトがエラーを出し、フォームのスクリプトが動かなくなっている
- 最適化プラグインで JavaScript の結合・遅延読み込みを有効にしたため、読み込みの順番が変わった
最適化の設定をいったん止めて試す、または次の手順でプラグインを1つずつ止めて、原因のプラグインを特定します。
プラグインとテーマの影響を切り分ける
原因が見つからない場合は、テーマを標準テーマ(Twenty Twenty-Five など)に切り替え、プラグインをすべて停止した状態で送信を試し、1つずつ有効に戻して症状が出るものを探します。本番サイトで試すと閲覧者にも影響するため、可能ならステージング環境で行います。WP-CLI が使えるなら、次のように一括で止めて戻せます。
# 有効なプラグインの一覧を保存してから、すべて停止する
wp plugin list --status=active --field=name > active-plugins.txt
wp plugin deactivate --all
# 1つずつ有効にして確認する(例)
wp plugin activate contact-form-7
まとめ
- まず開発者ツールの Network タブで、POST の応答コード(403・413・500・301/302・200)を確認する
post_max_sizeを超えると、PHP はエラーを返さずに送信内容を捨てる。値はini_set()ではなく、管理画面・php.ini・.user.ini・mod_php なら .htaccess で変える- 保存の一部が消えるなら
max_input_varsを疑う - 403 は WAF やセキュリティプラグイン、413 は Web サーバーの上限、301/302 は URL の不一致を確認する
- nonce の期限切れやページキャッシュ、JavaScript のエラーでも送信は失敗する
関連記事: