WordPressをサブディレクトリ運用でHeartbeatが404になる時の修正方法

WordPressをサブディレクトリ運用でHeartbeatが404になる時の修正方法

WordPressをサブディレクトリ運用でHeartbeatが404になる時の修正方法

なぜサブディレクトリ運用でHeartbeatが404になるのか

なぜサブディレクトリ運用でHeartbeatが404になるのか

WordPressにはホームURLとサイトURLの2つの設定がある。ルートで運用していればどちらもexample.comになるが、サブディレクトリ運用ではホームURLがexample.com、サイトURLがexample.com/wpのように分かれる。

この場合、AJAXのエンドポイントはexample.com/wp/wp-admin/admin-ajax.phpが正しい。ところが、Media Library Assistantにはjs/mla-define-ajaxurl-scripts.jsというファイルがあり、グローバル変数ajaxurlに /wp-admin/admin-ajax.phpというハードコードされたパスを代入するフォールバック処理が含まれている。

Heartbeatは本来heartbeatSettings.ajaxurlに正しいURLを持っているが、グローバル変数window.ajaxurlを優先して参照してしまう。このため、サブディレクトリの /wp部分が欠けたURLへリクエストが飛び、404を返す。

修正前(エラー状態)
window.ajaxurl = ‘/wp-admin/admin-ajax.php’
Heartbeatの送信先 → example.com/wp-admin/admin-ajax.php
結果 → 404 Not Found
↓
修正後(正常状態)
window.ajaxurl = ‘/wp/wp-admin/admin-ajax.php’
Heartbeatの送信先 → example.com/wp/wp-admin/admin-ajax.php
結果 → 200 OK
■ 404エラー ■ 正常応答

パスが1つ違うだけでHeartbeatが404になる流れを示している。

window.ajaxurlの値を確認して原因を特定する手順

window.ajaxurlの値を確認して原因を特定する手順

Ajax周りの404は別の原因でも発生するため、まずはwindow.ajaxurlを確認して切り分ける。ログイン中のフロントエンドで調査するのがポイントだ。

DevToolsのConsoleでwindow.ajaxurlを確認する

ChromeやFirefoxの開発者ツールを開き、Consoleタブにwindow.ajaxurlと入力して実行する。返ってきた値が /wp-admin/admin-ajax.phpのようになっていれば、サイトURL側の /wp部分が欠けている。管理画面ではajaxurlが最初から正しい値になるため、この症状はフロントエンドでしか現れない。

Networkタブで404になっているリクエストを探す

Networkタブを開き、admin-ajax.phpという文字列で絞り込む。404と表示されているリクエストが複数回発生していれば、Heartbeatが誤ったパスへ送信している。リクエストのURLを確認すると、/wpの部分が抜けていることが分かる。

プラグインを1つずつ無効化して切り分ける

Media Library Assistantを無効化してから再度window.ajaxurlを確認すると、値がundefinedになるか正しいURLに変わる。無効化で症状が消え、再有効化で再発するならそのプラグインが原因だ。ほかのプラグインでも同様のハードコードがある可能性があるため、1つずつ確認する。

ハードコードされたajaxurlを修正する実践手順

ハードコードされたajaxurlを修正する実践手順

根本的にはプラグイン側の修正を待つのが望ましい。ただし実務ではすぐに解消したいため、子テーマのfunctions.phpに一時的な修正を入れる手順を示す。

STEP 1 子テーマのfunctions.phpに修正コードを追加する
↓
STEP 2 ブラウザとキャッシュプラグインのキャッシュをクリアする
↓
STEP 3 DevToolsのNetworkタブでHeartbeatが200を返すことを確認する

子テーマへ修正を追加してから確認するまでの流れを3手順に整理した。

子テーマのfunctions.phpにwp_add_inline_scriptを追加する

以下のコードを子テーマのfunctions.phpに追記する。admin_urlを使い、WordPressの設定から正しいパスを動的に生成してwindow.ajaxurlに代入する。wp_footerで出力するため、プラグインのスクリプトが読み込まれた後に確実に上書きできる。

function fix_heartbeat_ajaxurl_for_subdirectory() {
    // 管理画面では不要なので除外する
    if ( is_admin() ) {
        return;
    }
    $ajax_url = admin_url( 'admin-ajax.php' );
    echo '' . "\n";
}
add_action( 'wp_footer', 'fix_heartbeat_ajaxurl_for_subdirectory', 999 );

wp_add_inline_scriptを使う手もある。ただし対象プラグインのスクリプトがHeartbeatより後に読み込まれる場合は上書きされるため、wp_footerで最後に定義するのが確実だ。子テーマを使っていない場合は、まず子テーマを作成してからfunctions.phpを編集する。

修正後にキャッシュをクリアして確認する

コードを追加したら、ブラウザキャッシュとキャッシュプラグインのキャッシュを削除する。その後、ログインしたままフロントエンドのページを開き、DevToolsのConsoleでwindow.ajaxurlを確認する。正しいパスになっていれば、NetworkタブでHeartbeatが200を返すようになる。

プラグイン本体の更新で根本解決する

Media Library Assistantでは、このajaxurlのハードコードについて開発元に報告されており、後続バージョンでの修正が見込まれる。まずは対象プラグインの最新版が出ていないかを確認する。ほかのプラグインで同じ症状を発見した場合は、開発元のサポートフォーラムやバグトラッカーに再現手順を添えて報告すると、根本修正につながりやすい。

再発を防ぐためにプラグイン側で確認したいポイント

再発を防ぐためにプラグイン側で確認したいポイント

同じ問題を避けるには、プラグイン開発者がajaxurlをハードコードしないことが最も重要だ。WP AJAX用のURLはadmin_urlかwp_localize_scriptで動的に渡すのがWordPressの標準的な作法である。サイト運営者側では、リニューアルやサブディレクトリ移設の際にHeartbeatの404が増えていないかを監視する。

アクセスログでadmin-ajax.phpに対する404が頻発していないか、定期的に確認すると早期発見できる。プラグインを新しく導入した直後に軽くフロントエンドを動かして、Networkタブを確認する習慣を付けるとよい。

よくある質問

Heartbeatが404を返すとサイトにどんな影響があるか

主にログイン中のユーザーに影響する。ページの自動保存、セッション期限の通知、投稿のロック処理などが不安定になる。編集作業中にサーバーと通信できないため、下書きの保存が失敗することがある。

Media Library Assistant以外のプラグインでも起きるか

起きる可能性がある。window.ajaxurlをハードコードで定義するプラグインはどれも同じ挙動になる。特に管理画面以外で独自のAjax処理を実装したプラグインで注意が必要だ。

wp_add_inline_scriptを追加するのは本番環境で安全か

管理画面以外のフロントエンドだけに適用するコードなので、比較的安全だ。ただしfunctions.phpの編集は必ず子テーマで行い、編集前にバックアップを取る。ステージング環境で1日程度様子を見るのが望ましい。

プラグインのJavaScriptファイルを直接編集して直せないか

直すことはできるが、プラグインの更新で上書きされるため推奨しない。子テーマのfunctions.phpに一時しのぎを置き、開発元の修正版を待つのが安全だ。

サブディレクトリからルートへ移設すれば解決するか

解決はするが、移設はサーバー設定やパーマリンク、検索エンジンへの影響が大きい。この不具合だけのために移設するのは過剰だ。まずはajaxurlの修正で対応するのが現実的だ。

この記事のポイント

  • サブディレクトリ運用ではadmin-ajax.phpの正しいパスが /wp/wp-admin/ になる
  • プラグインがwindow.ajaxurlをハードコードするとHeartbeatが404を繰り返す
  • DevToolsのConsoleでwindow.ajaxurlを確認して原因を切り分ける
  • wp_add_inline_scriptで正しいURLを渡すと即座に解消できる
  • 一時しのぎは子テーマのfunctions.phpに置き、根本修正はプラグイン更新を待つ
佐々木 太陽

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化 ・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門 ・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標 ・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意 ・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

この記事に関連するサービス

メッセージを残す