Logo

자바스크립트로 웹 페이지 이동하는 방법

웹에서 페이지 간의 이동은 일반적으로 하이퍼링크(Hyperlink)를 통해 이루어집니다. 즉, 사용자가 웹 페이지 상의 링크를 클릭하면 브라우저에서 해당 페이지가 열리게 됩니다. 웹 개발자는 이를 위해 HTML의 <a> 요소의 href 속성에 이동해야 할 URL을 명시해주죠.

하지만 웹 개발을 하다보면 부득이하게 자바스크립트로 페이지 이동을 처리해야하는 경우가 생기기 마련인데요. 대표적인 예로 미인증 사용자가 접근했을 때 바로 로그인 페이지로 강제 이동 시키는 것을 들 수 있겠습니다.

이번 글에서는 자바스크립트를 사용하여 페이지 이동을 구현하는 여러가지 방법에 대해서 알아보겠습니다.

window.location 프로퍼티

우선 브라우저 환경에서 자바스크립트 코드가 실행될 때 전역에서 접근이 가능한 window 객체의 location 프로퍼티에 대해서 간단하게 짚고 넘어가겠습니다.

location에는 말그대로 현재 브라우저 열려있는 페이지의 위치가 담겨 있는데요. 인터넷에서는 기본적으로 URL을 통해서 페이지를 식별하기 때문에, 쉽게 말해서 현재 페이지의 URL 정보라고 보시면 되겠습니다.

URL은 프로토콜(protocol), 호스트네임(hostname), 포트(port), 경로명(pathname) 등 다양한 요소로 구성되며 location을 통해서 우리는 각 구성 요소에 편하게 접근할 수 있습니다.

예를 들어, location.href에 접근하면 전체 URL을 문자열 형태로 얻을 수 있고, location.pathname에 접근하면 경로명을 얻을 수 있으며, location.search에 접근하면 쿼리 스트링(query string)을 얻을 수 있습니다.

이 정보는 자바스크립트에서 보통 window.location이나 document.location으로 접근하며 그냥 간단하게 location으로도 접근이 가능합니다.

window.location.hostname; // 'www.daleseo.com'
document.location.hostname; // 'www.daleseo.com'
location.hostname; // 'www.daleseo.com'

location 이나 location.href 변경

오래 전부터 웹 페이지를 이동할 때는 location 객체나 location 객체의 href 프로퍼티에 새로운 URL을 할당하는 방법을 많이 사용해왔습니다.

location = "https://www.daleseo.com";
location.href = "https://www.daleseo.com";

이 방법으로 페이지를 이동하면 방문 이력에 새로운 기록이 추가되며, 따라서 사용자는 브라우저에서 “뒤로 가기” 버튼을 눌러 이전 페이지로 돌아갈 수 있습니다.

history.back(); // 이전 페이지로 돌아감

그런데 이 페이지 이동 방법은 타입스크립트로 코드를 작성하기가 좀 까다롭다는 단점이 있는데요.

예를 들어서, location에 URL을 할당하려고 하면 아래와 같은 타입 에러가 발생할 것입니다.

location = "https://www.daleseo.com";
// Type 'string' is not assignable to type 'Location'.

혹시나 해서 window.location에 URL을 할당해보면 하면 이번에는 다른 타입 에러가 발생할 것입니다.

window.location = "https://www.daleseo.com";
// Type 'string' is not assignable to type 'Location | (string & Location)'.

그래서 이러한 타입 에러를 피하려면 다음과 같은 약간의 꼼수가 필요한데요. 😒

(window as Window).location = "https://www.daleseo.com";

그니마 location.href에 URL을 할당하는 것은 타입 에러는 일으키기 않는데요.

location.href = "https://www.daleseo.com";

하지만 이번에는 테스트를 작성하는 게 조금 난감해집니다… 😅

test("navigates to Dale Seo's Blog", () => {
  // 변경 전
  expect(location.href).toEqual("http://localhost/");

  // 꼼수
  Object.defineProperty(window, "location", {
    value: {
      ...location,
      href: location.href,
    },
  });

  // 변경
  location.href = "https://www.daleseo.com";

  // 변경 후
  expect(location.href).toEqual("https://www.daleseo.com");
});

location.assign() 메서드 호출

웹 페이지를 이동하는 두 번째 방법은 location 객체의 assign() 메서드를 호출하는 것입니다.

location.assign("https://www.daleseo.com");

이 방법도 첫 번째 방법처럼 방문 이력에 새로운 기록이 추가되기 때문에 이전 페이지로 돌아가는 것이 가능합니다.

history.back(); // 이전 페이지로 돌아감

첫 번째 방법과 달리 타입스크립트로 코딩할 때도 별 문제가 없고 테스트를 작성하기도 용이합니다.

test("navigates to Dale Seo's Blog", () => {
  // 변경 전
  expect(location.href).toEqual("http://localhost/");

  // 스파이
  jest.spyOn(location, "assign");

  // 변경
  location.assign("https://www.daleseo.com");

  // 변경 후
  expect(location.assign).toHaveBeenCalledTimes(1);
  expect(location.assign).toHaveBeenCalledWith("https://www.daleseo.com");
});

간혹 이 방법이 첫 번째 방법보다 느려서 첫 번째 방법을 선호하신다는 분들이 있는데요. 예전처럼 컴퓨터가 느릴 때면 몰라도 요즘에는 유의미한 성능 차이가 있다고 보기는 힘들 것 같습니다.

프로퍼티를 할당하는 것보다는 이렇게 메서드를 호출하는 편이 더 명시적이고, 특히 타입스크립트를 사용한다면 정신 건강에 더 이로울 것입니다.

location.replace() 메서드 호출

웹 페이지를 이동하는 세 번째 방법은 location 객체의 replace() 메서드를 호출하는 것입니다.

location.replace("https://www.daleseo.com");

이 방법은 첫 번째 방법과 두 번째 방법과 달리 현재 방문 기록을 덮어써버리기 때문에 이전 페이지로 돌아가는 것이 불가능합니다. 만약에 사용자가 뒤로 가기 버튼으로 이전 페이지의 이전 페이지로 이동할 것입니다.

history.back(); // 이전 이전 페이지로 돌아감

그러므로 이 방법은 사용자가 새로운 페이지가 이동한 후 이전 페이지로 돌아가는 것을 방지하고 싶은 경우에만 사용해야합니다.

마치면서

지금까지 자바스크립트로 페이지를 이동하는 3가지 방법에 대해서 알아보았습니다.

3가지 방법이 비슷한 것 같지만 미묘한 차이가 있으니 상황에 맞게 적절한 방법을 선택하는 것이 중요하겠습니다. 저는 개인적으로는 이전 페이지로 이동이 필요한지에 따라서 location.assign() 메서드나 location.replace() 메서드를 주로 사용하고 있습니다.

마지막으로 웹 접근성(accessibility) 측면에서 자바스크립트를 사용하여 페이지를 이동하는 것은 가능한 피하는 것이 좋습니다. 예를 들어, 링크 대신 버튼을 클릭하여 페이지 이동을 구현하면 스크린 리더 사용자에게 예상하기 어려운 경험이 될 수 있겠죠? HTML의 <a> 요소를 써도 되는데 굳이 자바스크립트를 쓰는 게 아닌지 의심하시면서 개발을 하시면 도움이 될 것 같습니다.