HTML5 History API(Pushstate?)を使用するための優れたチュートリアル[終了]


168

HTML5履歴APIを使用して、AJAXでロードされたコンテンツのディープリンクの問題を解決することを検討していますが、地面を離れるのに苦労しています。良いリソースを知っている人はいますか?

これは、リンクがJSをオンにしていない可能性があるリンクが送信される可能性を許容するための優れた方法と思われるため、使用したいと思います。JSを持つ誰かがリンクを持たない誰かにリンクを送信すると、多くの解決策が失敗します。

私の最初の調査では、JS内のHistory APIとpushStateメソッドを指摘しているようです。

http://html5demos.com/history

回答:


181

優れたチュートリアルについては、この機能に関するMozilla Developer Networkページが必要です:https : //developer.mozilla.org/en/DOM/Manipulating_the_browser_history

残念ながら、HTML5 History APIはすべてのHTML5ブラウザーで異なる方法で実装され(一貫性がなくバグが多い)、HTML4ブラウザーのフォールバックはありません。さいわい、History.jsはHTML5ブラウザーの相互互換性を提供し(すべてのHTML5ブラウザーが期待どおりに機能することを保証)、オプションでHTML4ブラウザーのハッシュフォールバックを提供します(データ、タイトル、pushState、replaceState機能のサポートの維持を含む)。

History.jsの詳細については、https//github.com/browserstate/history.jsをご覧ください。

Hashbangs VS Hashes VS HTML5 History APIに関する記事については、https//github.com/browserstate/history.js/wiki/Intelligent-State-Handlingをご覧ください。


25
恥知らずなセルフプラグ。優れた投稿とプラグインも。:)
Purag


28

ユーザーがディープリンクをコピーまたはブックマークして再度アクセスした場合、HTML5 pushstateを使用している間は、404になる直接のサーバーヒットになるので、準備をする必要があり、pushstate jsライブラリでも役に立たないことに注意してください。君は。最も簡単な解決策は、次のようにNginxまたはApacheサーバーに書き換えルールを追加することです。

Apache(使用している場合はvhost内):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>

Nginx

rewrite ^(.+)$ /index.html last;

それが本当の答えです。これはBaluptonのHistory.js wiki / tutorialsなどにはありません。実際、History.jsはハッシュを使用しないため、.htaccessリダイレクトを使用する必要があります。
adriendenat

13
理想的には、サーバー/アプリは、この書き換えの必要なしに、ルートに適切に応答する必要があります。
ショルシンガー、2012

同意しますが、Backbone.js、Spine、Emberなどの多くの最新のJavaScriptフレームワークの場合を除きます。これらはすべて基本的に「1ページ」のJavaScriptアプリケーションです。SEOなどの書き込みバックエンドテンプレートを提供するソリューションを考え出すこともできますが、それまではこれが必要になります。
Mauvis Ledford、2012

*正しい。私はここで、より詳細に本について書く:readystate4.com/2012/05/17/...
Mauvisレドフォード

6

HTML5履歴スペックは風変わりです。

history.pushState()popstateイベントを送出したり、それ自体で新しいページをロードしたりしません。国家を歴史に押し込むことだけが意図されていた。これは、単一ページアプリケーションの「元に戻す」機能です。popstateイベントを手動でディスパッチするか、を使用history.go()して新しい状態に移動する必要があります。アイデアは、ルーターがpopstateイベントをリッスンしてナビゲーションを実行できるというものです。

注意すべき点:

  • history.pushState()イベントをhistory.replaceState()ディスパッチしないでくださいpopstate
  • history.back()history.forward()、ブラウザの[戻る]ボタンや[進む]ボタンとは、派遣行うpopstateイベントを。
  • history.go()そして、history.go(0)フルページのリロードを行うと、送出されませんpopstateイベントを。
  • history.go(-1)(1ページ戻る)およびhistory.go(1)(1ページ進む)ディスパッチpopstateイベントを実行します。

このような履歴APIを使用して、新しい状態をプッシュし、popstateイベントを送出できます。

history.pushState({message:'New State!'}, 'New Title', '/link'); window.dispatchEvent(new PopStateEvent('popstate', { bubbles: false, cancelable: false, state: history.state }));

次にpopstate、ルーターでイベントをリッスンします。


1
それは私だけですnew PopStateEvent(...)か、それともIE11 では機能しないようですか?誰かが知っている回避策はありますか?
David Alan Hjelle 2015

:IE 11ニーズのようなもののように見える var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);
デヴィッド・アランHjelle

4

Davis.jsを試すことができます。これにより、利用可能な場合はpushStateを使用してJavaScriptでルーティングでき、JavaScriptがない場合はサーバー側のコードでリクエストを処理できます。



2

このjQueryプラグインをご覧ください。彼らのサイトにはたくさんの例があります。http://www.asual.com/jquery/address/


この場合も、JSがオフの場合、このソリューションは失敗するようです。履歴APIはmodrewriteと連動して機能するので、JSレイヤーからのリダイレクトを必要とせずに、リンクは常にサーバーによって最初のインスタンスで処理されます。
軽度のファズ

あなたはmodrewriteで正しい軌道に乗っています。履歴APIの管理と、ユーザーにJSがない場合の処理​​のソリューションは、実際には2つの別個のものです。JSがない場合は、標準のhrefとサーバー応答でユーザーを処理する必要があります。ヒストリーAPIは、ユーザーのブラウザーがサポートしていれば、「あるべき」のようなものとして構築できます。
Nathan Totten、

jQuery Address 1.3に同梱されているExpressとStateの両方のサンプルは、JavaScriptが無効になっている場合はかなりうまく機能します。2つ目は、mod_rewriteでPHPを使用します。
Rostislav、

まさに私のタクト。私は、JSなしでサイトを構築し、AJAX要素を追加してから、履歴を使用してURLを書き換え、ディープリンクを維持するつもりです。理論的には、サイトはどの段階でもAJAXに依存しないため、これまで見たどの方法よりも優れた方法である必要があります
マイルドファズ

1
-1 jQueryアドレスはHTML5 State APIの直接のポートではないため、データやタイトル、およびreplaceStateをサポートしていません。
balupton 2011年

2

StateRouter.jsと呼ばれる、History.jsの上に非常にシンプルなルーター抽象化を記述しました。開発の非常に初期の段階ですが、私が書いている単一ページアプリケーションのルーティングソリューションとして使用しています。あなたと同じように、History.jsは理解するのが非常に難しいことに気づきました。特にJavaScriptにかなり慣れていないため、低レベルの問題を解決するために、ルーティングの抽象化が本当に必要(または必要)であると理解できるまで、問題。

次の簡単なコード例は、それがどのように使用されるかを示しています。

var router = new staterouter.Router();
// Configure routes
router
  .route('/', getHome)
  .route('/persons', getPersons)
  .route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();

これは、その使用法を示すために私が作り出した小さなフィドルです。


1
このフィドルは、MacのChromeでは機能しません。エラーをスローします。(Uncaught ReferenceError:staterouter is not defined)
DrewT

@DrewTありがとう、github.comでの変更によりフィドルは壊れましたが、私はそれを回避しました。
aknuds1 2014

うん、迅速な対応に感謝します。
DrewT 2014

1

jQueryが利用可能な場合は、jQuery BBQを使用できます


JSをオフにすると失敗するようです。
軽度のファズ

それはおそらく本当です-まだ調べていません。すべてのjs-libraryベースのアプローチで問題が発生すると思います。これらは、URLのハッシュ部分の操作に基づいています。
スプラグマン

1
それがHTML5ヒストリーAPIの要点です-それは何も壊しません
balupton

2
@MildFuzzコンピュータは電源なしで失敗するようです!ID-10-Tエラーがあると思います...
Eric Hodonsky

1
皮肉にも、誤解されているのはあなたです
マイルドファズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.