【HTML】ping 属性でリンクがどれだけ踏まれたかを計測する

ページにはさまざまなリンクが張られていますが、そのリンクがどれだけ踏まれたかを計測するには、リダイレクトが良く使われてきました。しかし、いまは a 要素と area 要素で ping 属性を使うことができます。

今回は、これまでのリンククリック計測の方法と、そのメリットとデメリット、そして、a 要素と area 要素で使える ping 属性の使い方について詳しく見ていきましょう。

リダイレクトによる計測方法

ping といえばネットワーク機器の死活をチェックするコマンド名を思い浮かべる人が多いでしょう。しかし、今回紹介する ping 属性は、ネットワーク機器の死活監視とは異なります。

ウェブサイトを運営すると、どのページにどれくらいのアクセスがあったかを計測するのは当たり前です。そして、Google Analytics を使えば、誰でも簡単にアクセス解析ができます。

しかし、ページに埋め込まれたハイパーリンクがどれくらい踏まれたかについては、意外に計測が難しいのではないでしょうか。もちろん、ASP(アフィリエイトサービスプロバイダ)などが配信する広告のクリック数は ASP 側でクリック数を簡単に見ることができます。しかし、内部リンクや広告でない外部リンクのクリック数は簡単には分かりません。

これまで、そのようなクリックを計測するためにはリダイレクトが使われました。ユーザーがクリックするハイパーリンクの直接的なリンク先は目的のページではなく、計測サーバーの URL になります。その URL にはリダイレクト先となる目的のページの URL 情報もパラメータとして埋め込まれています。計測サーバーはクリックをカウントしたうえで、パラメータに埋め込まれた URL へリダイレクトします。

リダイレクト方式のメリットといえば、やはりすべてのブラウザーで確実にクリックを計測できる点でしょう。もちろん、Internet Explorer 11 でも問題ありませんし、それ以前のバージョンでも問題ありませんでした。このリダイレクト方式は、筆者が覚えていないほど昔から使われてきた方式です。

一方でデメリットもあります。計測サーバーの応答が少しでも遅いと、ページ遷移に時間がかかり、場合によってはユーザーが離脱してしまいかねません。

また、マークアップも面倒です。というのも、目的のリンク先 URL はパラメータとしてセットするため、URL エンコードの必要があります。

<a href="https://example.jp/ping.cgi?url=https%3A%2F%2Fwebfrontend.ninja%2F">
  Web Frontend Ninja
</a>

これをすべてのリンクに対して人力で行うのは現実的ではありません。動的に出力するページであればなんとかなりますが、静的なページばかりのウェブサイトの場合は、手間暇を考えると、どうしても計測場所が限定的になってしまいます。

ユーザーにとっても不便があります。リンクをマウスオーバーしたときにリンク先 URL がブラウザーのステータスバーに表示されますが、その URL が計測サーバーの URL になってしまいます。もしユーザーが知らないドメインだと、怪しまれてクリックしてもらえないかもしれませんね。

JavaScript による計測方法

リダイレクト方式とは別に、JavaScript を使う方法もあります。ハイパーリンクのクリックをキャッチして計測サーバーに情報を送ります。以下のサンプルは、class 属性に ping がセットされた a 要素を対象に、クリックされたら計測サーバーに通知を行います。

<a href="https://webfrontend.ninja" class="ping">ninja</a>
// class に "ping" がセットされた a 要素に click のイベント
// リスナーをセット
const link_list = document.querySelectorAll('a.ping');
for (let i = 0; i < link_list.length; i++) {
  link_list.item(i).addEventListener('click', sendPing);
}

// a 要素がクリックされたら通知をサーバーに送信
async function sendPing(event) {
  // デフォルトアクション (ナビゲーション) を止める
  event.preventDefault();

  // リンク元とリンク先の URL
  const from = window.location.toString();
  const to = event.currentTarget.href;

  // 計測サーバーに通知
  await fetch('https://example.jp/ping.cgi', {
    method: 'post',
    headers: { 'Conetnt-Type': 'application/json' },
    body: JSON.stringify({ from, to })
  });

  // リンク先にナビゲーション
  window.location.href = to;
}

この JavaScript コードでは fetch メソッドを使っていますが、もし Internet Explorer にも対応したいなら、XMLHttpRequest を使うこともできます。

この方法もリダイレクト方式と同じく、 計測サーバーの応答が少しでも遅いと、ページ遷移に時間がかかり、場合によってはユーザーが離脱してしまいかねません。

さらにもう一つ注意する点があります。ウェブサイトと計測サーバーのオリジンが異なると、CORS 制約によって fetchXMLHttpRequest が機能しません。計測サーバー側では、CORS に関するレスポンスヘッダーを適切にセットしないといけません。

ただし、リダイレクト方式とは違い、ユーザーがリンクをマウスオーバーしたときのデメリットはありません。

ping 属性を使った計測方法

前述の旧来の方式では、 計測サーバーの応答が少しでも遅いとページ遷移に時間がかかりユーザー体験を損なう可能性があるわけですが、そういったデメリットを克服するために用意されたのが ping 属性を使った計測方法です。

ping 属性には、計測サーバーの URL をセットします。以下の例では、ウェブサイトと計測サーバーが同一オリジンになっています。

<a href="https://webfrontend.ninja" ping="/ping.cgi">
  ninja
</a>

ユーザーがこのリンクをクリックすると、ナビゲーションと並行して /ping.cgi に POST メソッドで HTTP リクエストが送信されます。そのリクエストのボディ部は "PING" という文字列のみがセットされます。これ自体は何の役にも立ちません。必要な情報はリクエストヘッダーにセットされています。

ヘッダー名説明
Ping-Fromリンク元ページの URLPing-From: https://example.jp/test.html
Ping-Toリンク先ページの URLPing-To: https://webfrontend.ninja

もし、ウェブサイトと計測サーバーが異なるオリジンの場合(ドメインなどが違うクロスオリジンの場合)、基本的には、Ping-From ヘッダーが送信されず、計測サーバーでは Ping-To ヘッダーしか受け取ることができません。これは、前述の CORS のようにサーバー側で許可するかどうかという問題ではなく、ブラウザー側の挙動のためどうすることもできません。

ただし、ウェブサイトが非 SSL の場合は、計測サーバーとオリジンが異なってもブラウザーは Pint-From ヘッダーを計測サーバーに送信することになっています。とはいえ、現在において非 SSL でウェブサイトを運営することはほぼないと考えて良いため、事実上、オリジンが違えば Pint-From は利用できないと考えて差し支えないでしょう。

同時に複数の計測サーバーに通知する

実は、ping 属性には複数の計測サーバーの URL をセットすることが可能です。次のように半角スペース区切りで計測サーバーの URL をセットします。

<a 
  href="https://webfrontend.ninja"
  ping="https://example.jp/ping.cgi https://example.com/ping.cgi"
>ninja</a>

これはリダイレクト方式ではできなかった機能です。もちろん、計測サーバーが次の計測サーバーにリダイレクトし、最後の計測サーバーが目的のページへリダイレクトするなんてことも不可能ではありませんが、現実的ではありません。また、ナビゲーションのパフォーマンスが非常に悪くなります。

ping 属性を使う場合は、計測サーバーへの通知はブラウザーがバックグラウンドで行ってくれるため、ナビゲーションでユーザーを待たせることはありません。

ping 属性のメリットとデメリット

ping 属性を使うことのメリットは次の通りではないでしょうか。

  • ページナビゲーションにおいて、計測サーバーのパフォーマンスの影響を受けにくい
  • ユーザーがリンクをマウスオーバーしたときに、リンク先が分かる
  • マークアップが少し楽になる

一方、デメリットは次の通りでしょう。

  • 2022 年7 月現在、Internet Explorer 11 と Firefox は ping 属性をサポートしていない
  • ウェブサイトと計測サーバーがクロスオリジンの場合は、リンク先 URL しか得られない

なお、Firefox は実験的には ping 属性を実装済みです。いずれ Firefox でも ping 属性を使えるようになるかもしれません。

まとめ

ウェブサイトを運営していると、マーケティング上、どのページのどのリンクがクリックされやすいかを計測することは非常に重要な場合があります。Internet Explorer と Firefox を無視しても良いなら、マークアップの視点では ping 属性を使うのが楽で良いですね。とりわけスマートフォンが中心のウェブサイトなら ping 属性を使っても差し支えないのではないでしょうか。

とはいえ、計測サーバー側では ping 属性のリクエストに合わせて開発が必要になりますので、ping 属性が主流になるには少し時間がかかるかもしれませんね。

今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。

Share