JavaScript를 사용하여 새 페이지를로드하지 않고 브라우저에서 URL을 변경하십시오.


297

현재 페이지에 약간의 영향을 줄 수 있지만 브라우저에서 URL을 변경하여 사용자가 다시로드하거나 책갈피를 놓으면 새 URL이 사용되는 JavaScript 작업을 어떻게 수행합니까?

뒤로 버튼이 원래 URL을 다시로드하면 좋을 것입니다.

URL에 JavaScript 상태를 기록하려고합니다.


1
너무 좋을 것입니다. 물론 동일한 도메인 수정으로 제한됩니다. 그러나 경로를 클라이언트 측에서 제어하는 ​​것은 해시뿐만 아니라 여러 페이지에서 페이지를 다시로드하는 것이 많은 앱에서 "마지막 수단"이라는 논리적 인 단계입니다.
harpo

1
"정렬 한"잘 사용 pushState:for(i=1;i<50;i++){var txt="..................................................";txt=txt.slice(0,i)+"HTML5"+txt.slice(i,txt.length);history.pushState({}, "html5", txt);}
Derek 朕 會 功夫

이 효과의 예 : dujour.com
Ben

2
이러한 효과의 예 : facebook.com (경우에 라이트 개구 이미지)

이것은 좋은 질문입니다. 그러나 오늘날 이러한 방식으로 질문이 제기되면 "이것은 사람들이 당신을 위해 모든 코드를 작성하도록하는 사이트가 아닙니다"라는 문제로 인해 다운 투표되고 도약했을 것이라는 슬픈 상황입니다.
dewd

답변:


118

HTML 5에서는 history.pushState함수를 사용하십시오 . 예로서:

<script type="text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
   history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>

그리고 href :

<a href="#" id='click'>Click to change url to bar.html</a>

뒤로 단추 목록에 항목을 추가하지 않고 URL을 변경하려면 history.replaceState대신 사용하십시오.


내가 마지막으로 Chrome을 실험했을 때 맞습니다. 방금 우분투에서 Firefox 3.6으로 시도했지만 작동하지 않았습니다. FF에서 HTML5가 완전히 지원 될 때까지 기다려야한다고 생각합니다
clu3

15
샘플 코드는 developer.mozilla.org/en/DOM/Manipulating_the_browser_history 에서 잘라내어 붙여 넣습니다 . 실제로이 경우 foo와 bar의 의미를 설명하는 것이 귀찮습니다.
mikemaccana

2
foo와 bar는 아무 의미가 없으며 나중에 다시 가져올 수있는 임의로 정의 된 상태 객체입니다.
Paul Dixon 2012

3
@Paul : 그렇습니다, 위 기사는 그 정보를 제공합니다.
mikemaccana

2
이 의견을 게시 할 때 firefox chrome 및 safari에서 작동합니다. 그래도 아이 패드 또는 아이폰에서 모바일 사파리와 함께 운이 없다 :(
Sid

187

당신이 브라우저에서 작동하도록하려는 경우 그 지원하지 않는 history.pushStatehistory.popState 아직, "오래된"방법은 페이지를 다시로드가 발생하지 않습니다 조각 식별자를 설정하는 것입니다.

기본 아이디어는 window.location.hash필요한 상태 정보가 포함 된 값으로 속성 을 설정 한 다음 window.onhashchange 이벤트 를 사용하거나 지원하지 않는 이전 브라우저 onhashchange(IE <8, Firefox <3.6)를 정기적으로 확인하는 것입니다. 해시가 변경되었는지 확인하십시오.setInterval 예 )하고 페이지를 업데이트하십시오. 또한 초기 컨텐츠를 설정하려면 페이지로드시 해시 값을 확인해야합니다.

jQuery 를 사용하는 경우 브라우저가 지원하는 방법을 사용 하는 해시 변경 플러그인 이 있습니다. 다른 라이브러리 용 플러그인도 있다고 확신합니다.

브라우저가 ID가 일치하는 요소로 스크롤하기 때문에주의해야 할 사항은 페이지의 ID와 충돌하는 것입니다.


2
검색 엔진은 이러한 내부 링크 (해시)를 무시하지 않습니까? 내 시나리오에서는 스파이더 가이 링크에서도 선택하기를 원합니다.
Drew Noakes

3
@Drew는 내가 아는 한 검색 엔진이 페이지의 일부를 별도의 결과로 취급 할 수있는 방법이 없습니다.
Matthew Crumley


5
이벤트 setInterval를 검사하기 위해 사용 하는 대신 훨씬 더 채택 된 이벤트를 document.location.hash사용할 수 있습니다 hashchange. 각 표준을 지원하는 브라우저는 여기를 확인하십시오 . 현재 접근 방식은이를 지원하는 브라우저에서 push / popState를 사용하는 것입니다. 다른 사람들은 해시를 설정하고 hashchange지원하는 브라우저 만보 고 있습니다. IE <= 7은 히스토리를 지원하지 않지만 유용한 퍼머 링크로 남겨둔다. 그러나 누가 IE <= 7의 역사를 걱정합니까?
Irae Carvalho

2
@gabeDel 예. 웹 로그 분석에서 해시를 기록하지는 않지만 동일한 URL을 가지게됩니다. 더 좋은 방법은 _trackPageview새 페이지의 "실제"URL을 사용하여 수동으로 호출하는 것 입니다.
Matthew Crumley

37

window.location.href는 현재 URL을 포함합니다. 읽을 수 있고 추가 할 수 있으며 페이지를 다시로드 할 수 있습니다.

페이지에서 다시로드하지 않고 북마크 할 수 있도록 URL에 자바 스크립트 상태를 기록하려는 경우 # 다음에 현재 URL에 추가하고 onload 이벤트에 의해 트리거 된 자바 스크립트가 현재 구문 분석되도록합니다. 저장된 상태를 포함하는지 확인하기위한 URL입니다.

를 사용하면? # 대신에, 당신은 페이지를 새로 고침 할 것이지만,로드시에 저장된 상태를 파싱하기 때문에 이것은 실제로 문제가되지 않을 것입니다; 그러면 앞으로 및 뒤로 버튼도 올바르게 작동합니다.


2
URL에 자바 스크립트 상태를 기록하는 것은 내가하려고하는 것입니다.
Steven Noble

21

나는 이것이 불가능한 보안 문제 일 것이기 때문에 이것이 불가능하다는 것을 강력히 의심 할 것입니다. 예를 들어, 은행 로그인 페이지처럼 보이는 페이지를 만들고 주소 표시 줄의 URL을 실제 은행처럼 보이게 할 수 있습니다 !

아마도 왜 당신이 이것을하고 싶어하는지 설명한다면, 사람들은 대체 접근법을 제안 할 수 있습니다 ...

[2011 년 편집 : 2008 년에이 답변을 썼기 때문에 URL이 같은 출처에서 수정되는 한 HTML5 기술 에 대한 더 많은 정보가 밝혀 졌습니다.]


6
다시로드하지 않는 변경 사항이 경로, 쿼리 문자열 및 조각 (예 : 기관 (도메인 등)이 아님)으로 제한되는 경우 큰 문제가되지 않습니다.
Ollie Saunders

2
youtube.com/user/SilkyDKwan#p/u/2/gTfqaGYVfMg 는 가능한 예입니다. 비디오를 전환 해보십시오 :)
Spidfire

Matthew Chumley가 허용 된 답변에 언급 한 것처럼 location.hash (# 뒤에있는 모든 것) 만 변경할 수 있습니다.
Paul Dixon

2
페이스 북 해? Facebook은을 사용하여 다시로드 하지 않고 URL 변경합니다 history.pushState().
Derek 朕 會 功夫

폴 딕슨, 당신은 페이스 북의받은 편지함을 볼 수 있습니다 왼쪽에있는 이름을 클릭하면 URL이 변경되고 채팅 상자에 새 채팅이로드되고 페이지가 새로 고쳐지지 않습니다. 또한 WebGL에는 더 많은 사이트가 있습니다.
Dheeraj Thedijje

8

브라우저 보안 설정은 사람들이 표시된 URL을 직접 수정하지 못하게합니다. 발생할 수있는 피싱 취약점을 상상할 수 있습니다.

페이지를 변경하지 않고 URL을 변경하는 확실한 방법은 내부 링크 또는 해시를 사용하는 것입니다. 예 : http://site.com/page.htmlhttp://site.com/page.html#item1이 됩니다. 이 기술은 종종 hijax (AJAX + 기록 보존)에서 사용됩니다.

이 작업을 수행 할 때 종종 해시가있는 조치에 대한 링크를 href로 사용하고 요청 된 해시를 사용하여 조치를 결정하고 위임하는 jquery로 클릭 이벤트를 추가합니다.

나는 그것이 당신을 올바른 길로 인도하기를 바랍니다.


죄송하지만 귀하의 답변은 사실이 아닙니다. 예, URL을 변경할 수 있습니다.
Derek 朕 會 功夫

1
예, html5 기록 API를 사용할 수는 있지만 크로스 브라우저는 아니지만 다중 URL을 사용하여 해시 URL로 대체 할 수는 있습니다.
Jethro Larson 23.07에

8

jQuery 에는 jQuery-pusher 라는 브라우저의 URL을 변경하기위한 훌륭한 플러그인이 있습니다. 있습니다.

다음과 같이 JavaScript pushState와 jQuery를 함께 사용할 수 있습니다.

history.pushState(null, null, $(this).attr('href'));

예:

$('a').click(function (event) {

  // Prevent default click action
  event.preventDefault();     

  // Detect if pushState is available
  if(history.pushState) {
    history.pushState(null, null, $(this).attr('href'));
  }
  return false;
});


JavaScript 만 사용 history.pushState()상태를 변경 한 후 생성 된 XMLHttpRequest 객체의 HTTP 헤더에서 사용되는 리퍼러를 변경하는 .

예:

window.history.pushState("object", "Your New Title", "/new-url");

pushState () 메소드 :

pushState()상태 개체, 제목 (현재 무시 됨) 및 URL (선택 사항)의 세 가지 매개 변수를 사용합니다. 이 세 가지 매개 변수 각각에 대해 자세히 살펴 보겠습니다.

  1. state 객체 — state 객체는 JavaScript 객체로, 새로운 기록 항목과 연결됩니다.pushState() . 사용자가 새 상태로 이동할 때마다 popstate 이벤트가 시작되고 이벤트의 state 속성에 기록 항목의 상태 객체 복사본이 포함됩니다.

    상태 객체는 직렬화 할 수있는 모든 것이 될 수 있습니다. Firefox는 상태 객체를 사용자의 디스크에 저장하여 사용자가 브라우저를 다시 시작한 후 복원 할 수 있으므로 상태 객체의 직렬화 된 표현에 640k 문자의 크기 제한을 적용합니다. 직렬화 된 표현이 이것보다 큰 상태 객체를 전달하면pushState() 하면 메소드에서 예외가 발생합니다. 이보다 더 많은 공간이 필요한 경우 sessionStorage 및 / 또는 localStorage를 사용하는 것이 좋습니다.

  2. 표제 — Firefox는 현재이 매개 변수를 무시하지만 나중에 사용할 수도 있습니다. 빈 문자열을 여기에 전달하면 나중에 메소드를 변경하지 않아도 안전합니다. 또는 이동중인 주에 짧은 제목을 전달할 수도 있습니다.

  3. URL — 새 기록 항목의 URL은이 매개 변수로 제공됩니다. 브라우저는을 호출 한 pushState()후이 URL을로드하려고 시도하지 않지만, 예를 들어 사용자가 브라우저를 다시 시작한 후 나중에 URL로드를 시도 할 수 있습니다. 새로운 URL은 절대적 일 필요는 없습니다. 상대적인 경우 현재 URL을 기준으로 해결됩니다. 새 URL은 현재 URL과 동일한 출처 여야합니다. 그렇지 않으면 pushState()예외가 발생합니다. 이 매개 변수는 선택 사항입니다. 지정하지 않으면 문서의 현재 URL로 설정됩니다.



3

Facebook의 사진 갤러리는 URL에서 #hash를 사용하여이 작업을 수행합니다. 다음은 몇 가지 URL 예입니다.

'다음'을 클릭하기 전에 :

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507

'다음'을 클릭 한 후 :

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507

해시 뱅 (#!) 바로 뒤에 새 URL이옵니다.



2

나를 위해 일하는 것은- history.replaceState()다음과 같은 기능입니다-

history.replaceState(data,"Title of page"[,'url-of-the-page']);

이 페이지를 다시로드하지 않습니다, 당신은 자바 스크립트의 이벤트와 함께 사용할 수 있습니다


1

페이지의 부모 경로가 동일하고 새로운 것만 추가되는 한 가능한지 궁금합니다.

따라서 사용자가 페이지에 있다고 가정 해 봅시다. http://domain.com/site/page.html 그러면 브라우저가 나를 할 수 location.append = new.html 있고 페이지가됩니다. http://domain.com/site/page.htmlnew.html브라우저는 페이지를 변경하지 않습니다.

또는 사람이 get 매개 변수를 변경하도록 허용하십시오 location.get = me=1&page=1.

따라서 원본 페이지가 http://domain.com/site/page.html?me=1&page=1되고 새로 고침되지 않습니다.

#의 문제는 해시가 변경 될 때 데이터가 캐시되지 않는다는 것입니다 (적어도 그렇게 생각하지 않습니다). 따라서 새로운 페이지가로드 될 때마다 Ajax 가 아닌 뒤로 및 앞으로 버튼이 페이지의 데이터를 캐시 할 수 있으며 데이터를 다시로드하는 데 시간을 소비하지 않습니다.

내가 본 것에서 Yahoo 기록은 이미 모든 데이터를 한 번에로드합니다. Ajax 요청을 수행하지 않는 것 같습니다. 따라서 div다른 방법으로 초과 근무를 처리 하는 데 a 를 사용하면 각 기록 상태에 대해 해당 데이터가 저장되지 않습니다.


1

내 코드는 다음과 같습니다

//change address bar
function setLocation(curLoc){
    try {
        history.pushState(null, null, curLoc);
        return false;
    } catch(e) {}
        location.hash = '#' + curLoc;
}

그리고 행동 :

setLocation('http://example.com/your-url-here');

$(document).ready(function(){
    $('nav li a').on('click', function(){
        if($(this).hasClass('active')) {

        } else {
            setLocation($(this).attr('href'));
        }
            return false;
    });
});

그게 다야 :)


1

내가 제시하는 더 간단한 대답,

window.history.pushState(null, null, "/abc")

/abc브라우저 URL에서 도메인 이름 뒤에 추가됩니다 . 이 코드를 복사하여 브라우저 콘솔에 붙여넣고 URL이 " https://stackoverflow.com/abc "로 변경되는 것을 확인하십시오 .


0

나는 성공했다 :

location.hash="myValue";

#myValue현재 URL에 추가 됩니다. 로드 페이지에서 이벤트를 트리거해야하는 경우이를 사용 location.hash하여 관련 값을 확인할 수 있습니다 . 그냥를 제거해야합니다 #반환 된 값에서 location.hash

var articleId = window.location.hash.replace("#","");
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.