◆ 別記事のカウントと入れ替わることがある
◆ ブラウザ側のバグのような挙動
  ◆ iframe で開かれたページが src で指定したものとは別のもの(別の場所の iframe で開かれたもの)

ちょっと前にこのブログのソーシャルボタンリストに拍手ボタンを追加しました
記事一覧を見るときに数字を少し意識して見ていたのですが おかしな増減が起きていました
最初は勘違いかな?くらいに思ってましたが 何度か発生していて完全におかしいという確証も取れました

カウントがおかしい

ブログトップを開いたときに見える記事はだいたいカウントが頭に残ってます
0 だったはずなのに 1 になってる というときがあって最初は誰かがクリックしたのだと思いました
しかし また開き直すと 0 に戻ってます
拍手ボタンは増えるのみで減らす機能はないはずです
何度かリロードして確認すると 0 が正しいようです
直接取得の API にアクセスしても 0 です
また逆に実際には 6 だったものが 0 になってたこともありました

特徴的な数字があるページで確認するとわかりやすいですが ランダムな数字になるわけじゃなくて どこかの記事と入れ替わってるようです

調べてみる

拍手数取得の API へのアクセス

devtools を開いておいて 異常が発生したときに発生したリクエストを調べます
一覧ページでは 25 記事が表示されます

拍手数を取得する API を呼び出すリクエスト数を見ると 25 でした
一致しています

URL から記事 ID を取り出して一覧に表示される 25 記事と比較します
すると一致していませんでした

実際にアクセスされていたものでは 同じ記事 ID へ 2 回リクエストが起きているものがいくつかありました
合計が 25 回ですから一覧には並んでいるのにアクセスされていない記事も存在しています

イメージとしてはこういう感じです

一覧に表示されている記事 ID:
100, 200, 300, 400, 500

拍手数取得の API が呼び出された記事 ID:
100, 200, 200, 400, 400

↑ 200 と 400 が 2 回呼び出されていて 300 と 500 は呼び出されていない

iframe の src

拍手ボタンは iframe で表示されていますが iframe の src に指定する URL が間違っているのでしょうか?
こういうのは自動で出力されていて ときどき間違うなんてことはなさそうですけど

$$("#main h1 a").map(x => x.href.match(/(\d+)\.html/)[1]).toSorted().join("\n")
=== $$("#main iframe").map(x => x.src).filter(x => x.includes("clap")).map(x => x.match(/\/(\d+)\//)[1]).toSorted().join("\n")
// true

確認してみると一致しています

iframe の中身

そうなるとどうして同じ URL が 2 回アクセスされているのかわかりません
なんとなく iframe の中身を見てみました

すると……

clapbug

まさかの iframe に指定した URL の記事 ID と iframe のページ内部に記載されている記事 ID が別になってます
iframe の src や data-article-id では 87712487 となっているのに その iframe の中では articleId 変数に代入している値は 87682465 です

このバグはひどい

自身の URL の記事 ID を自動で出力するだけなのにどうして別の ID になるの??

articleId は使われてなかった

ライブドアブログのバグだなっと納得したとき気になる部分が目に入りました
拍手数を取得するコードはこうなっていました

  var $clapCount   = $('#clap-count');
var $button = $('#button');
var articleId = '87681570';
var currentCount = 0;
$.ajax({
url: './',
method: 'GET',
cache: false,
dataType: 'json',
}).done(function(data) {
var count = data.count || 0;
currentCount = data.count || 0;
$clapCount.html(count.toString().replace(/(\d)(?=(\d{3})+$)/g , '$1,'));
var width = $button.outerWidth(true) + 1;
window.parent.postMessage([articleId, width].join(':'), "*");
});

リクエストに articleId を使っていないです
リクエストする URL は 「./」 です
自身の URL に基づいています
URL の 1 つ親階層に記事 ID があるので articleId が間違っていようと正しい URL にアクセスされるはずです

でも最初に調べたように devtools のネットワークタブでは実際にリクエストされた URL は間違ったものでした

iframe の URL

もしかして iframe 内のページの URL は articleId と等しいのでしょうか?
src では 87712487 なのに 実際に iframe が開いているのは 87682465 で そのせいで変数 articleId にも 87682465 が入っていたということでしょうか

devtools の console でコンテキストをその iframe に合わせて location.href を表示して記事 ID を確認してみました

87682465

でした

まとめ

iframe 内に自動で遷移するような処理がなくリダイレクトが発生したログもない以上 iframe の src に指定したものと別のページが開かれていた というのが原因みたいです
こうなるとブラウザのバグでしょうね
キャッシュとかが影響してそうです

確認したのは Chrome/Edge 117 です

なんというか少しホラーな気分を味わいました