HTML5 History API (Pushstate?) 사용을위한 유용한 자습서 [닫기]


168

HTML5 히스토리 API를 사용하여 AJAX로드 컨텐츠와의 딥 링크 문제를 해결하려고 노력하고 있지만 시작하기 위해 고심하고 있습니다. 좋은 자원을 아는 사람이 있습니까?

링크가 전송되지 않았을 가능성을 허용하는 좋은 방법 인 것처럼 JS를 사용하지 않을 수 있으므로 이것을 사용하고 싶습니다. JS를 가진 사람이없는 사람에게 링크를 보내면 많은 솔루션이 실패합니다.

내 초기 연구는 JS 내의 History API와 pushState 메소드를 가리키는 것으로 보입니다.

http://html5demos.com/history

답변:


181

훌륭한 자습서를 위해이 기능에 대한 Mozilla 개발자 네트워크 페이지 만 있으면됩니다. https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

불행히도 HTML5 히스토리 API는 모든 HTML5 브라우저에서 다르게 구현되며 (일관되지 않고 버그가 있음) HTML4 브라우저에 대한 대체는 없습니다. 다행스럽게도 History.js 는 HTML5 브라우저에 대한 상호 호환성을 제공하고 (모든 HTML5 브라우저가 예상대로 작동하도록 보장) 선택적으로 HTML4 브라우저에 대한 해시 폴백 (데이터, 제목, pushState 및 replaceState 기능에 대한 지원 유지 포함)을 제공합니다.

History.js에 대한 자세한 내용은 https://github.com/browserstate/history.js를 참조 하십시오.

Hashbangs VS Hashes VS HTML5 히스토리 API에 대한 기사는 여기를 참조하십시오. https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling


25
뻔뻔한 자체 플러그. 그래도 훌륭한 게시물과 플러그인. :)
Purag


28

사용자가 딥 링크를 복사하거나 책갈피에 추가하여 다시 방문하면 HTML5 푸시 상태를 사용하는 동안 명심하십시오. 그러면 직접 서버 히트가 발생하여 404가되어 준비가 필요하며 푸시 상태 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>

니 진스

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

그게 정답입니다. 이것은 Balupton의 History.js 위키 / 자습서 등 어디에도 없습니다. 실제로, History.js는 해시를 사용하지 않으므로 .htaccess 리디렉션을 사용해야합니다!
adriendenat

13
이상적으로 서버 / 앱은이 재 작성 없이도 경로에 적절히 응답해야합니다.
sholsinger

Backbone.js, Spine, Ember 등과 같은 많은 최신 JavaScript 프레임 워크의 경우를 제외하고는 동의합니다. 이들은 모두 본질적으로 "한 페이지"JavaScript 응용 프로그램입니다. SEO에 대한 쓰기 백엔드 템플릿을 제공하는 솔루션을 해결할 수는 있지만 그 동안 이것이 필요할 것입니다.
Mauvis Ledford

*권리. 이에 대한 자세한 내용은 readystate4.com/2012/05/17/…
Mauvis Ledford

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

IE 11은 다음과 같은 것이 필요합니다 : var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);
David Alan Hjelle

4

당신은 시도 할 수 Davis.js을 당신이 자바 스크립트를하지 않고는 서버 측 코드가 요청을 처리 할 수 있습니다 사용할 수와 pushState를 사용하여 자바 스크립트에서 라우팅을 제공합니다.



2

이 jQuery 플러그인을 살펴볼 수 있습니다. 그들은 그들의 사이트에 많은 예제를 가지고 있습니다. http://www.asual.com/jquery/address/


다시 말하지만 JS가 꺼져 있으면이 솔루션이 실패하는 것 같습니다. 히스토리 API는 modrewrite와 함께 작동하여 JS 계층에서 리디렉션 할 필요없이 서버가 첫 번째 인스턴스에서 링크를 항상 처리 할 수있는 힘을 가지고 있다고 생각합니다.
Mild Fuzz

당신은 modrewrite와 함께 올바른 길을 가고 있습니다. 히스토리 API를 관리하고 사용자에게 JS가 없을 때 처리하는 솔루션은 실제로 두 가지입니다. JS가 없으면 표준 href 및 서버 응답으로 사용자를 처리해야합니다. 히스토리 API는 사용자의 브라우저가 지원한다면 일종의 "좋은 것"으로 구축 될 수 있습니다.
Nathan

jQuery Address 1.3과 함께 제공되는 Express 및 State 샘플은 JavaScript가 비활성화 된 경우 상당히 잘 작동합니다. 두 번째는 mod_rewrite와 함께 PHP를 사용합니다.
Rostislav

정확히 내 전술. JS없이 사이트를 만들고 AJAX 요소를 추가 한 다음 기록을 사용하여 URL을 다시 작성하여 딥 링크를 유지하려고합니다. 이론적으로는 어떤 단계에서든 사이트가 AJAX에 의존하지 않기 때문에 내가 본 것보다 더 나은 방법이어야합니다.
Mild Fuzz

1
jQuery Address는 HTML5 State API의 직접 포트가 아니므로 -1-데이터 또는 제목 및 replaceState를 지원하지 않습니다.
balupton

2

StateRouter.js 라는 History.js 위에 매우 간단한 라우터 추상화를 작성했습니다 . 개발 초기 단계에 있지만 작성중인 단일 페이지 응용 프로그램에서 라우팅 솔루션으로 사용하고 있습니다. 당신과 마찬가지로, 나는 JavaScript를 처음 접할 때 History.js를 이해하기가 매우 어렵다는 것을 알게되었습니다. 문제.

이 간단한 예제 코드는 사용 방법을 보여 주어야합니다.

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가 정의되지 않았습니다)
DrewT

@DrewT 감사합니다. github.com의 변경으로 인해 바이올린이 망가졌지만 그 문제를 해결했습니다.
aknuds1

응, 빠른 응답에 감사합니다.
DrewT

1

jQuery를 사용할 수 있으면 jQuery BBQ를 사용할 수 있습니다


JS가 꺼져 있으면 실패하는 것 같습니다.
Mild Fuzz

그것은 아마 사실입니다-그것을 보지 않았습니다. 모든 js 라이브러리 기반 접근 방식에서 문제가 있다고 생각합니다. URL의 해시 부분 조작을 기반으로합니다.
sprugman

1
그것이 HTML5 History API의 요점입니다. 아무 것도 깨지 않습니다
balupton

2
@MildFuzz 컴퓨터가 전원 공급 장치없이 실패한 것 같습니다! 나는 ... 당신이 ID-10-T 오류가 있다고 생각
에릭 Hodonsky

1
아이러니하게도, 잘못 이해 한 것은 당신입니다
Mild Fuzz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.