# 時間がたつと自動で再読み込みや転送をするページ

Source: https://easeweb.dev/learn/meta-refresh
Topics: 制限時間と動き > ページがタイマーで再読み込みやリダイレクトをしない (WCAG 2.2.1)
The fix: meta refreshを削除し、ページの最後を「買い物を続ける」リンクにして、利用者が自分で離れるまでページが残るようにします。ページを移動させるスクリプトのタイマーやRefreshヘッダーも同じように基準を満たさないため、meta要素をどちらかに置き換えても修正になりません。移転したページは、代わりにサーバーですぐに転送します。
Test with: keyboard, screen reader, zoom
References: https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html https://www.w3.org/WAI/WCAG22/Techniques/failures/F40 https://www.w3.org/WAI/WCAG22/Techniques/failures/F41 https://www.w3.org/WAI/WCAG22/Techniques/failures/F58 https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-refresh https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Refresh https://dequeuniversity.com/rules/axe/4.10/meta-refresh

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

## 場面

文具店の購入手続きは、注文完了ページで終わります。「ご注文ありがとうございます。注文番号は4821です。10月23日（金）にお届けします」。最後の行には「10秒後にショップへ戻ります」とあり、実際に10秒たつと、ブラウザーは自動でショップのトップページへ移ります。利用者が行き止まりのページに取り残されないようにと、ページのheadに1行入れてあるためです。

ちらっと見て満足する人には、10秒で十分です。しかし、スクリーンリーダーの利用者は、ページのタイトルと見出しを聞いたあと、注文番号の読み上げにたどり着く前にトップページの読み上げが始まってしまうことがあります。注文番号もお届け日も聞けないまま、ページが移ります。画面拡大ソフトで拡大している人は、まだ注文番号を探しています。ヘッドポインターで番号をコピーしている人は、選択している途中です。タイマーを止める方法も、時間を延ばす方法もページにはありません。

## 確認できる問題

達成基準2.2.1「タイミング調整可能」は、コンテンツが設定するすべての時間制限を対象にしています。一定時間でページが自動で移動するのも時間制限の一つです。ページで知りたいことは、タイマーが切れる前に読み取るしかありません。時間制限には、利用者が解除できるか、既定の10倍以上に調整できるか、警告を受けてから20秒以上の猶予のうちに簡単な操作で延長でき、それを10回以上繰り返せるか、のどれかが求められます。20時間より長い制限、オークションのようなリアルタイムのイベント、その活動に欠かせない制限は例外です。注文完了ページはどれにも当たりません。「10秒後にショップへ戻ります」は警告にはなっていますが、延長する手段はありません。

W3Cは、こうした作り方を2.2.1の失敗例として挙げています。F40は、この例のように、遅延の後に別のページへ転送するmeta refreshです。F41は、1分ごとに再読み込みする試合速報のページのように、同じページを再読み込みするmeta refreshです。F58は、同じ指示をサーバーが `Refresh` HTTPヘッダーとして送るもので、ブラウザーはmeta要素と同じように従います。タイマーから `location.href` を設定するスクリプトも、F40が述べる転送と同じ結果になります。遅延が0のmeta refreshは、誰かが読み始める前にすぐ転送するため、基準を満たします。

## 利用者への影響

注文の確認がいちばん必要な人ほど、タイマーに間に合いません。注文確認のメールは後で届くかもしれませんが、注文番号やお届け日を読むつもりだったのはこのページで、ショップはそこから利用者を移してしまいます。

## 自動チェックとAIの限界

axeの `meta-refresh` は、遅延が0秒より長く20時間以下のmeta refreshを報告するため、このページは見つかります。ほかの二つの方法は検出できません。`Refresh` ヘッダーはページの中にないため、この診断ではレスポンスのヘッダーを読み、`ew:refresh-header` として報告します。スクリプトのタイマーは動いたときにしか現れず、ページを読み込んで離れるスキャンは、その前に終わっていることがあります。そこで、この診断ではページが自動で始めるタイマーを見張り、ページを再読み込みしたり別のページへ移したりするものを確認に回します（`ew:timed-reload-manual-check`）。実際にページが移るかどうかは、人が確かめるしかないためです。AIアシスタントに「ショップに戻すお礼のページ」を頼むと、このmeta要素を書くことがあり、meta要素は不適合だと伝えると、`setTimeout(() => { location.href = '/'; }, 10000)` に書き換えることがあります。これでスキャンの警告は消えますが、問題は残ります。

## 修正前：10秒後に移動する注文完了ページ

```html
<head>
  <title>Order placed – Northfold</title>
  <meta http-equiv="refresh" content="10; url=/">
</head>
<body>
  <main>
    <h1>Thank you for your order</h1>
    <p>Your order number is 4821.</p>
    <p>Your parcel will arrive on Friday 23 October.</p>
    <p>You will be taken back to the shop in 10 seconds.</p>
  </main>
</body>
```

ブラウザーは、利用者が何をしていても、注文完了ページを開いてから10秒でトップページへ移動します。ページにはそう書かれていますが、止めることも、時間を延ばすこともできません。

## 修正後：準備ができたら戻れるリンク

```html
<head>
  <title>Order placed – Northfold</title>
</head>
<body>
  <main>
    <h1>Thank you for your order</h1>
    <p>Your order number is 4821.</p>
    <p>Your parcel will arrive on Friday 23 October.</p>
    <p>
      <a href="/">Continue shopping</a>
    </p>
  </main>
</body>
```

meta要素をなくせば、ページは利用者が自分で離れるまで残り、準備ができたらリンクでショップへ戻れます。行き止まりのページに利用者を残さないという、タイマーの目的も果たせます。変更は最小限で、1行を消し、最後の文をリンクにするだけです。

## 実装の判断

**タイマーで再読み込みするページ。** 試合速報、発車案内、配送状況の追跡のように `<meta http-equiv="refresh" content="60">` を持つページは、1分ごとに再読み込みし、そのたびにスクリーンリーダーは先頭から読み直します。新しい内容は、利用者が求めたときに読み込めるリンクやボタンで提供します。ページが自動で最新の状態を保つ必要があるなら、変わる部分だけを取得してその場に書き込み、その前に一時停止ボタンを置きます。ほかの内容と並んで自動で更新される部分は、2.2.2「一時停止、停止、非表示」の対象にもなるためです。

**移転したページ。** 「このページは移転しました。5秒後に新しいページへ移動します」も同じ失敗です。代わりに、サーバーで301か308のステータスを返して転送します。これなら何かが表示される前に済みます。

**Refreshヘッダー。** レスポンスの `Refresh: 10; url=/` は、サーバーから送るmeta要素にあたり、フレームワークのレスポンス処理やWebサーバーの設定で付けられます。これも同じように削除します。ページのソースには何も現れないため、ヘッダーはブラウザーのネットワークパネルで確認してください。

**カウントダウンでは解決しません。** 残りの秒数を数えて表示したり、残り時間を書いたりしても、ページが移動することは伝わりますが、止める手段がないことは変わりません。タイマーに表示を足すのではなく、タイマーそのものをなくしてください。

**セッション。** 一定時間でログアウトさせたり、「セッションの有効期限が切れました」のページへ移したりするのは時間制限で、別のガイドで扱います：[警告も延長もないセッションタイムアウト](/ja/learn/time-limits)。AAAの3.2.5「要求による変化」はさらに踏み込み、コンテキストの変化は利用者が求めたときにだけ起こるか、そうした変化を利用者が無効にできることを求めています。これは別のトピックで扱います。

## 修正の確認

1. テンプレートで `http-equiv="refresh"` を探し、ページの種類ごとにネットワークパネルでレスポンスヘッダーの `Refresh` を確認し、スクリプトで `setTimeout` や `setInterval` の中の `location.reload`、`location.assign`、`location.replace`、`location` への代入を探す。どれもタイマーでページを再読み込みしたり転送したりしていないことを確認する。
2. 注文完了ページを開き、1分以上何もせずに置く。ページがそのまま残り、アドレスが変わらないことを確認する。
3. スクリーンリーダーで、いつもの速さでページを先頭から読む。注文番号とページの最後までたどり着くことを確認する。
4. キーボードだけで、Tabで「買い物を続ける」に移ってEnterを押す。ショップへ移動することを確認する。
5. 画面拡大ソフトで拡大し、自分のペースでページ全体を見て回る。自分で選ぶまでページが移動しないことを確認する。

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ページのテンプレート、購入手続き、サーバーのヘッダーを変更した際は、再度確認します。

## 制限

このガイドが扱うのは、一定時間の後にページが自動で再読み込みや転送をする場合です。自動で動いたり流れたりする内容は[一時停止できない、流れる文字、カルーセル、アニメーション](/ja/learn/moving-content)で、利用者をログアウトさせるセッションは[警告も延長もないセッションタイムアウト](/ja/learn/time-limits)で扱います。注文完了ページの前に表示される、ほかの事業者の決済や予約のページも同じ購入手続きの一部なので、時間で戻る仕組みがないか確認してください。ページを読み込んだときに何を読み上げるかはスクリーンリーダーによって違うため、利用者が使っているスクリーンリーダーで確認してください。

---

このガイドをコーディングエージェントで使う: MCP https://easeweb.dev/mcp（設定は https://easeweb.dev/ja/services/developers）
