LoginSignup
10
8

More than 5 years have passed since last update.

pushStateのstateObjでハマった。

Last updated at Posted at 2015-02-27

どもども、フロントはそんなに得意じゃないのですが、かなりハマったバグだったので一応Qiitaに投稿しておこうとおもいます。

pushStateすると、Chromeが謎の挙動

現象はちょっと説明しにくいので割愛しますが、pushStateするとChromeのブラウザバックの挙動が謎の動きをするようになった。

原因を調査していたら、pushStateのstateObjectの扱いが問題だったことがわかったので共有しておきたいと思います。

pushStateとは

詳しくはリンク先を参照してください。

state オブジェクト — state オブジェクトは pushState() によって作成される新しい履歴エントリに関連付けられる JavaScript オブジェクトです。ユーザーが新しいエントリに移動すればいつでも、popstate イベントが発火して、履歴エントリの state オブジェクトのコピーがイベントの state プロパティへと含まれることとなります。

state オブジェクトは何であってもシリアライズされます。Firefox はユーザーのディスクに state オブジェクトを保存し、ユーザーがブラウザを再起動した際に state オブジェクトを復元するため、シリアライズされた状態での state オブジェクトの最大文字数は640000文字と、サイズの制限がされています。シリアライズ後にこの最大文字数を上回ることになる state オブジェクトを pushState() に渡した場合、pushState()は例外を投げます。これを上回るスペースが必要な場合、sessionStorage または localStorage の使用を推奨します。

今回重要なのはココ↓

state オブジェクトは何であってもシリアライズされます。

実際にハマった部分

最初、stateObjをテキストにしていました。

var stateObj = "bar";
history.pushState(stateObj, "page 2", "bar.html");

これでもね、一応期待する挙動は実現できるんですよ。なので特に違和感なくそのまま実装していたんですよね…。

どうやらオブジェクト化しないとダメらしい

  • ↑のところにも書いてあるので当たり前なのだけど、オブジェクトでないとダメみたいでした。
  • オブジェクトならStringオブジェクトとかでもいいのかどうかは未確認

解決後

var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");

あー、スッキリ。
ドキュメントはちゃんと見ようね。というお話でした。

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8