1. 7.5 セッション履歴およびナビゲーション
      1. 7.8.1 ブラウジングセッション
      2. 7.8.2 ブラウジングコンテキストのセッション履歴
      3. 7.8.3 Historyインターフェイス
      4. 7.8.4 Locationインターフェイス

7.8 セッション履歴およびナビゲーション

7.8.1 ブラウジングセッション

ブラウジングセッションは…である。 ブラウジングセッションの定義については、whatwg/html issue #4782およびwhatwg/html issue #5350を参照のこと。 `Cross-Origin-Opener-Policy`ヘッダーまたはナビゲーションのために置き換えることができないことを除いて、これはトップレベルブラウジングコンテキストにほぼ類似している。

トップレベルブラウジングコンテキストには、ブラウジングセッションであるブラウジングセッションが関連付けられている。

環境設定オブジェクトenvironmentブラウジングセッションは、次の手順を実行した結果である:

  1. Assert: environment's global object is a Window.

  2. Return environment's global object's browsing context's top-level browsing context's browsing session.

7.8.2 ブラウジングコンテキストのセッション履歴

ブラウジングコンテキスト内のDocumentの配列は、そのセッション履歴である。子ブラウジングコンテキストを含む各ブラウジングコンテキストは、個別のセッション履歴を持つ。ブラウジングコンテキストのセッション履歴は、セッション履歴のエントリーのフラットなリストから成る。

ブラウジングコンテキストセッション履歴における各Documentオブジェクトは、同じ基礎となるセッション履歴をすべてモデル化しなければならない、一意なHistoryオブジェクトに関連付けられる。


セッション履歴エントリーは、以下のアイテムをもつ構造体である:

シリアライズされた状態は、ユーザーインターフェイスの状態を表すオブジェクトを(StructuredSerializeForStorage経由で)シリアライズしたものである。非公式に"状態オブジェクト"と呼ぶこともあるが、これは著者から提供されたユーザーインターフェイスの状態を表すオブジェクトであり、あるいは、シリアライズされた状態をデシリアライズ(StructuredDeserialize経由で)して作成されたオブジェクトでもある。

ページは、シリアライズされた状態をセッション履歴に追加することができる。ユーザー(またはスクリプト)が履歴に戻るとき、これらはデシリアイズされスクリプトに返されるため、著者は1ページのアプリケーションでも"ナビゲーション"メタファーを使用できるようになる。

シリアライズされた状態は、主に2つの目的で使用されることを意図している:1つは、事前に準備された状態の記述をURLに格納することで、単純な場合には著者が解析を行う必要がないようにすることである(ただし、ユーザーによって渡されたURLを処理するためには解析が必要になるので、マイナーな最適化に過ぎない)。もう1つは、現在のDocumentインスタンスにのみ適用され、新しい Documentを開いた場合に再構築しなければならないため、URL には保存されないような状態を作者が保存できるようにすることである。

後者の例は、ユーザーが戻った場合同じ場所にアニメーションさせることができるように、ポップアップdivがアニメーション化するために作られた正確な座標を追跡するようなものになるだろう。またその代わりに、前後に行くときに、情報が再度フェッチする必要がないよう、URL内の情報に基づいてサーバーからフェッチされるデータのキャッシュにポインターを保持するために使用できる。

スクロール復元モードは、エントリーに移動するときに、ユーザーエージェントが永続化されたスクロール位置(存在する場合)を復元すべきかどうかを示す。スクロール復元モードは次のいずれかである:

"auto"
ユーザーエージェントは、ナビゲーション時にスクロール位置を復元する責任がある。
"manual"
ページはスクロール位置を復元する責任があり、ユーザーエージェントは自動的に復元を試みない。

セッション履歴内の複数の連続したエントリーは、同じ文書を共有することができる。これは、通常のナビゲーションを介して最初のエントリーに到達し、かつhistory.pushState()を介して次のエントリーが追加された場合に発生する可能性がある。または、フラグメントへのナビゲーションを介して発生する可能性がある。

同じDocumentを共有する(したがって、特定の文書の単に異なる状態である)すべてのエントリーは、定義により連続する。


任意の時点で、セッション履歴のエントリーの1つは、現在のエントリーである。これは、ブラウジングコンテキストアクティブ文書を表すエントリーである。現在のエントリーであるそれぞれのエントリーは、この仕様で定義されるアルゴリズムによって変更される。たとえばセッション履歴走査中など。

現在のエントリーは通常、ナビゲーション時に作成される最初のエントリーである。しかし、上記のように、同じ文書を共有する連続したエントリーの1つにすることもできる。

ブラウジングコンテキスト内の各Documentはまた、最新のエントリーを持つことができる。これは、ブラウジングコンテキストセッション履歴が最後にたどられたDocumentのエントリーである。 Documentが作成されるとき、最初は最新のエントリーを持たない。

7.8.3 Historyインターフェイス

History

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Window/history

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
window.history.length

ジョイントセッション履歴内のエントリーの数を返す。

window.history.scrollRestoration [ = value ]

セッション履歴の現在のエントリーのスクロール復元モードを返す。

セッション履歴の現在のエントリーのスクロール復元モードを変更する設定が可能である。

window.history.state

オブジェクトにデシリアライズされた、現在のシリアライズされた状態を返す。

window.history.go([ delta ])

ジョイントセッション履歴内のステップの指定した数の前後に進む。

ゼロ差分は、現在のページをリロードする。

差分が範囲外の場合、何もしない。

window.history.back()

ジョイントセッション履歴内の1つのステップに戻る。

前のページが存在しない場合、何もしない。

window.history.forward()

ジョイントセッション履歴内の1つのステップに進む。

次のページが存在しない場合、何もしない。

window.history.pushState(data, "")

指定されたdataが関連付けられたセッション履歴に新しいエントリーをプッシュする。 現在のエントリーのURLがコピーされ、新しいエントリーのURLに使用される。

(2番目のパラメーターは歴史的な理由で存在し、省略することはできない。空の文字列を渡すことは慣例的なものである。)

window.history.pushState(data, "", url)

指定されたdataが関連付けられ、そのURLがurlに設定される新しいエントリーをセッション履歴にプッシュする。

現在のDocumentがURLをurl書き換えることができない場合、"SecurityError" DOMExceptionが投げられる。

(2番目のパラメーターは歴史的な理由で存在し、省略することはできない。空の文字列を渡すことは慣例的なものである。)

window.history.replaceState(data, "")

現在のセッション履歴エントリーに保存されているデータをdataに更新する。

(2番目のパラメーターは歴史的な理由で存在し、省略することはできない。空の文字列を渡すことは慣例的なものである。)

window.history.replaceState(data, "", url)

現在のセッション履歴エントリーに保存されているデータをdataに更新し、そのURLをurlに更新する。

現在のDocumentがURLをurl書き換えることができない場合、"SecurityError" DOMExceptionが投げられる。

(2番目のパラメーターは歴史的な理由で存在し、省略することはできない。空の文字列を渡すことは慣例的なものである。)

トップレベルブラウジングコンテキストジョイントセッション履歴は、ジョイントセッション履歴の現在のエントリーを除いて削除されたそれぞれのセッション履歴において現在のエントリーであるすべてのエントリーとともに、トップレベルブラウジングコンテキストを共有するすべての完全にアクティブなDocumentオブジェクトのすべてのブラウジングコンテキストに属するすべてのセッション履歴の結合である。

ジョイントセッション履歴の現在のエントリーは、最近そのセッション履歴内の現在のエントリーになったエントリーである。

ジョイントセッション履歴内のエントリーは、それぞれのセッション履歴に追加された時点で時系列に並べられる。各エントリーはインデックスを持つ。最古のエントリーのインデックスは0を持ち、後続のエントリーは連続して増加する整数(1、2、3など)を番号付けされる。

ブラウジングコンテキスト内の各Documentは、異なるイベントループがあるかもしれないので、ジョイントセッション履歴の実際の状態は、不明瞭にできる。たとえば、2つの兄弟iframe要素は、同時に1つの一意な生成元から別のものに互いに横断でき、それらの正確な順序は明確に定義されないかもしれない。それらは後にお互いを知るかもしれないので、同様に、それらはジョイントセッション履歴の長さについて同意しないかもしれない。

A Document document can have its URL rewritten to a URL targetURL if the following algorithm returns true:

  1. Let documentURL be document's URL.

  2. If targetURL and documentURL differ in their scheme, username, password, host, or port components, then return false.

  3. If targetURL's scheme is an HTTP(S) scheme, then return true. (Differences in path, query, and fragment are allowed for http: and https: URLs.)

  4. If targetURL's scheme is "file", and targetURL and documentURL differ in their path component, then return false. (Differences in query and fragment are allowed for file: URLs.)

  5. If targetURL and documentURL differ in their path component or query components, then return false. (Only differences in fragment are allowed for other types of URLs.)

  6. Return true.

document's URLtargetURLcan have its URL rewritten
https://example.com/homehttps://example.com/home#about
https://example.com/homehttps://example.com/home?page=shop
https://example.com/homehttps://example.com/shop
https://example.com/homehttps://user:pass@example.com/home
https://example.com/homehttp://example.com/home
file:///path/to/xfile:///path/to/x#hash
file:///path/to/xfile:///path/to/x?search
file:///path/to/xfile:///path/to/y
about:blankabout:blank#hash
about:blankabout:blank?search
about:blankabout:srcdoc
data:text/html,foodata:text/html,foo#hash
data:text/html,foodata:text/html,foo?search
data:text/html,foodata:text/html,bar
data:text/html,foodata:bar
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43#hash
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43?search
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43blob:https://example.com/anything
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43blob:path

DocumentURLのみが重要であり、その生成元は重要ではないことに注意する。継承された生成元をもつabout:blank Document、サンフォボックスiframe、またはdocument.domainセッターが使用されている場合のように、これらが一致しないことがある。

ユーザーはいくつかの座標に常にあり、ユーザーが後で再開するための特定の座標に対応するページをブックマークできるような、ユーザーがラインに沿って移動できるゲームを考える。

そのようなゲームでx=5位置を実装する静的ページは次のようになる:

<!DOCTYPE HTML>
<!-- this is https://example.com/line?x=5 -->
<html lang="en">
<title>Line Game - 5</title>
<p>You are at coordinate 5 on the line.</p>
<p>
 <a href="?x=6">Advance to 6</a> or
 <a href="?x=4">retreat to 4</a>?
</p>

このようなシステムの問題点は、毎回ユーザーがクリックするとページ全体をリロードする必要があることにある。ここで、代わりにスクリプトを使用して、リロードを行うための別の方法:

<!DOCTYPE HTML>
<!-- this starts off as https://example.com/line?x=5 -->
<html lang="en">
<title>Line Game - 5</title>
<p>You are at coordinate <span id="coord">5</span> on the line.</p>
<p>
 <a href="?x=6" onclick="go(1); return false;">Advance to 6</a> or
 <a href="?x=4" onclick="go(-1); return false;">retreat to 4</a>?
</p>
<script>
 var currentPage = 5; // prefilled by server
 function go(d) {
   setupPage(currentPage + d);
   history.pushState(currentPage, "", '?x=' + currentPage);
 }
 onpopstate = function(event) {
   setupPage(event.state);
 }
 function setupPage(page) {
   currentPage = page;
   document.title = 'Line Game - ' + currentPage;
   document.getElementById('coord').textContent = currentPage;
   document.links[0].href = '?x=' + (currentPage+1);
   document.links[0].textContent = 'Advance to ' + (currentPage+1);
   document.links[1].href = '?x=' + (currentPage-1);
   document.links[1].textContent = 'retreat to ' + (currentPage-1);
 }
</script>

スクリプトをもたないシステムにおいて、前の例と同じように動作する。しかし、同じ体験に対するネットワークアクセスが存在しないので、スクリプトをサポートするユーザーは現在はるかに速く移動できる。さらに、経験に反して、ユーザーは単にナイーブなスクリプトベースのアプローチ、ブックマーク、およびセッション履歴の移動が依然として動作する必要がある。

上記の例において、pushState()メソッドへのdata引数は、サーバーに送信されるものと同じ情報であるが、スクリプトはURLにユーザーが移動するたびに解析する必要はないので、より便利な形式となる。

ほとんどのアプリケーションは、すべての履歴エントリーに同じスクロール復元モード値を使用したいと考えている。これを実現するために、できるだけ早くscrollRestoration属性を設定して(たとえば、文書のhead要素の最初のscript要素で)、履歴セッションに追加されたエントリーが確実に希望のスクロール復元モードになるようにする。

<head>
  <script>
       if ('scrollRestoration' in history)
            history.scrollRestoration = 'manual';
  </script>
</head>
   

7.8.4 Locationインターフェイス

Document/location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

Window/location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Windowオブジェクトは、Locationオブジェクトの一意なインスタンスに関連付けられており、Windowオブジェクトの作成時に割り当てられる。

document.location [ = value ]
window.location [ = value ]

現在のページの位置とLocationオブジェクトを返す。

別のページにナビゲートするために、設定可能である。

Locationオブジェクトは、Documentブラウジングコンテキストに属するアクティブ文書URLの表現を提供し、historyオブジェクトのエントリーを追加または置換することによって、ブラウジングコンテキストのセッション履歴の現在のエントリーを変更可能にする。

location.toString()
location.href

LocationオブジェクトのURLを返す。

与えられたURLにナビゲートするように、設定可能である。

location.origin

Locationオブジェクトの生成元を返す。

location.protocol

Locationオブジェクトのスキームを返す。

変更されたスキームと同じURLにナビゲートするように、設定可能である。

location.host

LocationオブジェクトのURLのホストとポートを返す(スキームのデフォルトポートと異なる場合)。

変更されたホストおよびポートと同じURLにナビゲートするように、設定可能である。

location.hostname

Locationオブジェクトのホストを返す。

変更されたホストと同じURLにナビゲートするように、設定可能である。

location.port

Locationオブジェクトのポートを返す。

変更されたポートと同じURLにナビゲートするように、設定可能である。

location.pathname

Locationオブジェクトのパスを返す。

変更されたパスと同じURLにナビゲートするように、設定可能である。

location.search

LocationオブジェクトのURLのクエリーを返す(空でない場合は先頭の"?"を含む)。

(先頭の"?"を無視して)変更されたクエリーと同じURLにナビゲートするように、設定可能である。

location.hash

LocationオブジェクトのURLのフラグメントを返す(空でない場合は先頭の"#"を含む)。

(先頭の"#"を無視して)変更されたフラグメントと同じURLにナビゲートするように、設定可能である。

location.assign(url)

与えられたURLにナビゲートする。

location.replace(url)

セッション履歴から現在のページを削除し、与えられたURLにナビゲートする。

location.reload()

現在のページをリロードする。

location.ancestorOrigins

親ブラウジングコンテキストからトップレベルブラウジングコンテキストまで、祖先ブラウジングコンテキストの生成元を列挙するDOMStringListオブジェクトを返す。