カテゴリー
WordPress

WordPressが出力するリンクURLのスキーマを強制的に書き換える。

WordPress の出力する HTML では、内部リンクも含めてすべての URL が絶対リンクになっています。

2018年より、主要なWebブラウザが 非SSLなサイトに対して「保護されていない通信」や「この接続は安全ではありません」とメッセージが表示されるようになったので、常時SSL化を進めています。WordPress の投稿にメディアを埋め込んでいる場合等に埋め込み時の従来の「http://〜」で始まるURL が残っている場合があります。

この場合URLが残っているページを表示した際に下記のような「混在コンテンツ」の警告が Webブラウザに表示されることがあります。

Mixed Content: The page at ‘https://example.com/’ was loaded over HTTPS, but requested an insecure image ‘http://example.com/wp-content/uploads/image20170301.png’. This content should also be served over HTTPS.

画像ファイルであれば、大きな問題にならないのかもしれませんが、CSS や JavaScript で発生した場合はファイルが読み込まれないため、レイアウトが崩れたり、スクリプトエラーが発生することもあります。

根本的な対策としては、すべての絶対 URL を 「http://〜」な URL に書き換えることですが、コンテンツの担当者が異なる等のいろいろな事情により簡単にできない場合もあります。

せめて、WordPress の内部リンクだけでも何とか対策したいと思ったので、下記のファンクションを導入して表示の際に URL のスキーマとホスト名を WordPress のサイトURLで置き換えるようにしてみました。

function my_homeurl_replace_tbnfn($buf) {
    $new_url = get_home_url();
    $old_url = str_replace( '/', '\\/', preg_replace( '/https*/', 'https*', $new_url ) );
    $buf = preg_replace( '/'.$old_url.'/', $new_url, $buf);
    return $buf;
}

function my_buf_start_tbnfn() {
    ob_start('my_homeurl_replace_tbnfn');
}

function my_buf_end_tbnfn() {
    if (ob_get_length()) {
        ob_end_flush();
    }
}

add_action('after_setup_theme', 'my_buf_start_tbnfn');
add_action('shutdown', 'my_buf_end_tbnfn');

プログラムの中身は単純で、php の ob_start() 関数で、出力内容をバッファリングして、「WordPressサイトのURL」を強制的に常時SSL化されたWordPressのサイトURLに書き換えて出力しています。

WordPress のサイトURLが、常時SSL化されていて、「get_home_url()」で「https://〜」な URL を取得できることが前提になっています。