브라우저 히스토리 조작하기

현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

DOM의 window 객체는 history 객체를 통해 브라우저 히스토리에 접근할 수 있습니다. history 객체는 사용자 히스토리에서의 앞 뒤 이동이 가능하도록 유용한 메서드와 속성들을 제공하며, history stack의 내용을 조작할 수 있게 합니다.

히스토리에서의 이동하기

back(), forward(), go() 메서드 등을 이용하여 사용자 히스토리에서의 앞 뒤 이동이 가능합니다.

앞으로 가기 & 뒤로 가기

히스토리에서 뒤로 가기 위해서는 아래 명령어를 실행합니다.

window.history.back();

이 명령어의 실행결과는 마치 사용자가 브라우저 툴바에서의 Back button 을 클릭한 것과 같이 동작합니다.

이와 비슷하게, 아래 명령어를 실행하여 히스토리에서 앞에서 갈 수도 있습니다. (마치 브라우저 툴바의 Forward button의 역할)

window.history.forward();

히스토리에서 특정 위치로 가기

go() 메서드를 이용하여 session history에서 특정 페이지를 호출할 수 있습니다. 그 특정 페이지는 현재 페이지의 위치에 기준하여 상대적인 위치 정보를 갖습니다 (현재 페이지의 상대적인 index는 0이 됩니다) 

back() 메서드를 사용한 효과처럼, 한 페이지 뒤로 가기 위해서는 아래 명령어를 실행합니다.

window.history.go(-1);

forward() 메서드처럼 한 페이지 앞으로 가기 위해서는 아래 명령어를 실행합니다.

window.history.go(1);

유사한 방식으로, 두 페이지를 앞으로 가거나 뒤로 가는 것이 가능합니다. Index 값에 따라서 말이죠,

history stack의 length 속성을 이용하여 페이지가 몇 페이지로 구성되어 있는지도 파악이 가능합니다.

var numberOfEntries = window.history.length;
참고 : 인터넷 익스플로러는 (IE) string URLs 를 go() 메서드의 변수로 넘기는 것을 지원합니다. 이 것은 표준방식이 아니며, Gecko에서 지원이 되지 않습니다.

히스토리 엔트리를 추가 및 변경하기

HTML5는 사용자가 히스토리 엔트리를 추가하거나 변경할 수 있는 history.pushState()와 history.replaceState() 메서드들을 제공합니다. 이 메서드들은 window.onpopstate() 이벤트와 연관이 있습니다.

history.pushState() 활용은 HTTP 헤더안에 있는 referrer를 변경 할 수 있습니다. 이 referrer는  사용자가 상태를 변경한 후에 생성되는 XMLHttpRequest 객체의 HTTP에서 사용됩니다. 또한 이 referrer는 XMLHttpRequest 객체가 생성되는 시점에서의 window 객체 다큐먼트의 URL이 됩니다.

예제

http://mozilla.org/foo.html 에서 다음 자바스크립트를 실행한다고 가정합시다.

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

실행결과는 URL 주소를 http://mozilla.org/bar.html 로 바꾸지만, 브라우저는 bar.html 로딩하지 않고 심지어 해당 html파일의 존재유무를 점검하지도 않습니다.

사용자가 http://google.com 에 접속하고나서 back 버튼을 클릭한다고 가정합니다. 이 시점에서, URL의 주소는 http://mozilla.org/bar.html 를 가리킬 것이고, 웹 페이지는 위에서 저장한 stateObj의 복사본을 포함하고 있는 popstate 이벤트를 발생시킵니다. 이 페이지 자체는 foo.html 처럼 보이지만, 페이지의 내용은 popstate 이벤트 상태에서 변경되었을 것 입니다.

만약 우리가 back 버튼을 다시 누르면, URL은 http://mozilla.org/foo.html 로 변경되고, 다큐먼트는 또 다른 popstate 이벤트를 얻게 됩니다. 이번에는 null state 객체를 얻습니다. 여기서도 역시, 뒤로 가는 것 자체가 이 바로 앞 전 단계에 있던 다큐멘트의 내용을 바꾸진 않습니다. 하지만, 다큐멘트는 popstate() 이벤트가 발생함에 따라 stateObj의 내용을 변경할 것 입니다.

pushState() 메서드

pushState()는 세개의 변수를 갖습니다. state / title / URL. 이 변수들에 대해 상세히 알아봅니다.

  • state object — state 객체는 pushState()에 의해 생성된 새로운 history entry를 포함하고 있는 자바스크립트 객체입니다. 사용자가 새로운 상태로 이동할 때 마다, popstate 이벤트가 발생하고, 이 이벤트의 state 프로퍼티는 history entry's state 객체를 포함합니다.

  • state 객체는 항상 동기화가 될 수 있습니다. 왜냐하면 Firefox는 state 객체들을 사용자의 디스크에 저장합니다. 그리고 그 state 객체들은 사용자가 브라우저를 재시작 하여도 다시 사용할 수 있습니다. state 객체의 동기화 사이즈는 640k로 제한됩니다. 만약 사용자가 이 사이즈보다 큰 동기화 객체를 pushState()로 보낸다면, 메서드는 예외 처리 할 것입니다. 만약 사용자가 이 보다 더 큰 사이즈를 원한다면, sessionStorage나 localStorage를 사용할 것을 권장드립니다.

  • title — Firefox 는 현재 이 변수를 무시합니다 (아마 나중에 사용될 수 있습니다). 빈 스트링을 지정해 놓는 것이 나중에 있을 변화에 대비하는 좋은 자세 일 것입니다. 대안으로는, 이동하고자 하는 state 마다 짧은 타이틀을 부여하는 것입니다.

  • URL — 새로운 히스토리 엔트리의 URL은 이 변수에 기준합니다. pushState() 콜 이후에는 브라우저가 이 URL을 로딩하지 않는 것을 명심하시기 바랍니다. 하지만 아마 나중에도 사용될 수 있습니다, 예를 들면, 사용자가 브라우저를 다시 시작했을 때처럼 말이죠. 새롭게 할당되는 URL은 현재의 URL에 기준하기 때문에, 절대적인 값을 부여할 필요가 없습니다. 새로운 URL은 기존의 URL에서 기준해야 합니다. 그렇지 않으면 pushState()는 예외를 발생시킵니다. 이 변수는 optional 합니다. 만약 정해지지 않으면, 현재 사용하는 URL이 default 값으로 됩니다.

Note: In Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) through Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the passed object is serialized using JSON. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the object is serialized using the structured clone algorithm. This allows a wider variety of objects to be safely passed.

pushState() 함수 실행은 마치 window.location = "#foo" 실행하는 것과 같습니다. 두 실행결과 현재 다큐멘트에 연관되어 있는 또다른 히스토리 엔트리를 생성하고 실행시킵니다. 하지만 pushState() 를 사용하면 다음과 같은 혜택이 있습니다.

  • pushState() 함수로 새롭게 생성된 URL은 현재 URL에 기준합니다. 이와는 반대로, window.location은 해쉬 값을 변경했을 때, 같은 다큐멘트에 머무르게 됩니다.
  • 만약 URL 변경이 싫다면, 변경하지 않아도 됩니다. 반대로, window.location = "#foo" 는 현재 해쉬 값이 #foo 가 아니었을 때만 새로운 히스토리 엔트리를 생성합니다.
  • 새로운 히스토리 엔트리에 임시 데이터를 사용할 수도 있습니다. 해쉬에 기준한 접근방식은, 사용자가 모든 데이터를 짧은 string 으로 인코딩하게 합니다.
  • 브라우저가 title 프로퍼티를 이용하면, 이 데이터는 해쉬와는 별개로 사용될 수 있습니다.

만약 새로운 URL과 이전 URL의 주소는 다를지라도, hash 값이 동일하면 pushState()는 절대 hashchange() 이벤트를 발생시키지 않습니다. 

XUL 다큐멘트에서는, 특정한 XUL 다큐멘트가 생성됩니다.

다른 다큐멘트에서는, null 네임스페이스 URI를 가진 요소가 생성됩니다.

replaceState() 메서드

history.replaceState()는 history.pushState()와 동일하게 동작합니다. replaceState()는 새로운 히스토리를 하나 생성하는 대신에, 현재의 히스토리 엔트리를 변경합니다. 하지만 global browser history에서 새로운 엔트리는 생성됩니다.

replaceState()는 state 객체나, 사용자의 동작에 따라 현재 히스토리 엔트리의 URL을 업데이트 하려고 할 때 매우 유용합니다.

Note: In Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) through Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the passed object is serialized using JSON. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the object is serialized using the structured clone algorithm. This allows a wider variety of objects to be safely passed.

popstate 이벤트

popstate 이벤트는 현재 활성화된 히스토리 엔트리에 변화가 있을 때 마다 실행된다. 만약 pushState 함수나 replaceState 함수에 의해 현재 활성화되어 있는 히스토리 엔트리가 조작 및 변경된다면, popstate 이벤트의 state 객체는 히스토리 엔트리의 state 객체에서 복사된다.

사용법은 window.onpopstate() 을 참고한다.

현재 상태 읽기

페이지가 로딩이 되었을 때, state 객체는 아마 null이 아닐 수 있습니다. 이것은, 예를 들어, 페이지가 pushState()나 replaceState()를 이용하여 state 객체를 설정하고, 브라우저를 재시작했을 때 가능합니다. 페이지 reloading을 했을 때, popstate 이벤트가 아닌 onload() 이벤트가 발생됩니다. 그러나, history.state 프로퍼티를 접근했다면, state 객체는 마치 popstate 발생시에 얻었을 객체와 동일하게 될 것입니다.

popstate 이벤트를 기다릴 필요 없이, 아래와 같은 명령어를 이용하여 현재 히스토리 엔트리의 상태에 접근할 수 있습니다.

var currentState = history.state;

예제

AJAX 웹 사이트의 완성된 예제를 보고 싶다면, 이 링크를 참고합니다. Ajax navigation example.

Specifications

Specification Status Comment
WHATWG HTML Living Standard
The definition of 'History' in that specification.
Living Standard No change from HTML5.
HTML5
The definition of 'History' in that specification.
Recommendation Initial definition.

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
replaceState, pushState 5 4.0 (2.0) 10 11.50 5.0
history.state 18 4.0 (2.0) 10 11.50 6.0
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
replaceState, pushState ? ? ? ? ?
history.state ? ? ? ? ?

See also

문서 태그 및 공헌자

 이 페이지의 공헌자: joshua1988
 최종 변경: joshua1988,