본문 바로가기
javascript/javascript

[javascript] 자바스크립트 Failed to execute 'replaceState' on 'History': A history state object with URL 에러 해결하기!

by 산코디 2023. 1. 20.

자바스크립트에서 history를 다루다 보면 'Failed to execute 'replaceState' on 'History': A history state object with URL '...' cannot be created in a document with origin 'null' and URL'와 같은 에러가 발생하는데, 해당 에러는 history의 replaceState() 기능을 사용하다 보면 발생하는 에러다.



history.replaceState()

history.replaceState() 함수는 HTML5의 History API에 속하는 메서드 중 하나로, 브라우저의 세션 기록(히스토리)을 수정하여 현재 페이지의 URL과 상태를 변경한다. 이 함수를 사용하면 페이지를 새 URL로 변경하고 브라우저 히스토리를 업데이트할 수 있다. 주로 페이지의 URL을 변경하거나 페이지 상태를 업데이트하는 데 사용된다.

히스토리 관리
history.replaceState() 함수는 브라우저의 히스토리 스택을 수정하며, 이전 페이지의 히스토리 엔트리를 제거하고 새로은 엔트리로 대체한다.

페이지 URL 변경

주로 사용되는 기능 중 하나는 현재 페이지의 URL을 변경하는 것이다. 이를 통해 페이지의 URL을 동적으로 업데이트할 수 있다.

상태 객체

history.replaceState() 함수는 새로운 히스토리 엔트리에 대한 상태 객체를 제공하며, 이 객체는 popstate 이벤트가 발생할 때 사용된다. 상태 객체는 페이지의 현재 상태를 나타내며, 필요에 따라 사용자 지정 데이터를 저장할 수 있다.

URL 및 제목 설정
새로운 히스토리 엔트리의 URL과 제목을 설정할 수 있다. 하지만 대부분의 브라우저에서는 제목을 무시하고 URL만 적용된다.

보안 및 권한
history.replaceState() 함수의 호출은 보안 정책에 따라 제한될 수 있으며, 브라우저의 보안 정책에 따라 현재 페이지의 origin과 새로운 URL의 origin이 일치해야 한다.


위의 정리한 내용과 같이 history.replaceState() 함수의 특징을 먼저 정리해 봤고, 해당 함수의 특징에 따라 어떤 상황에 에러가 발생할 수 있는지 다양한 예제 코드를 통해서 에러가 발생하는 상황을 살펴보도록 하자.


로컬 파일에서 실행

일반 HTML 파일을 직접 실행되는 스크립트에서 replaceState()를 사용하게 되는 경우 해당 에러가 발생할 수 있다.

<!DOCTYPE html>
<html lang="en">
<script>
try {
    history.replaceState({}, '', 'test');
} catch (error) {
    console.error(error.message);
}
</script>
</html>

위의 코드는 일반 HTML 문서에서 history.replaceState() 함수를 이용해서 경로를 'test'로 지정하였는데, 위의 HTML 파일을 직접 실행하게 되면 에러가 발생하게 된다.
예를 들어, HTML 파일명을 test.html이라고 생성하였고, 브라우저에 바로 띄우게 되면 URL은 C:/test.html와 같이 연결이 된다. 이때, 위의 코드를 실행하게 되면 C:/test.html#/test와 같이 URL이 변경되고, 콘솔에서는 에러가 발생하게 된다.
그렇기 때문에 history.replaceState() 함수를 사용할 때에는 서버를 통해서 화면을 띄우는지 먼저 파악하고나서 기능 테스트를 해야 한다.


CORS 제한

스크립트가 현재 문서와 다른 origin에서 실행되고 있을 때, 즉 스크립트가 로드된 페이지와 replaceState()가 호출되는 페이지의 origin이 다를 때 발생할 수 있다. 보안상의 이유로 이전 페이지의 상태를 변경하는 것을 방지하는 것이므로, 코드를 통해서 알아보자.

<!DOCTYPE html>
<html lang="en">
<body>
<button onclick="changeURL()">Change URL</button>

<script>
    function changeURL() {
        // CORS 제한으로 인해 replaceState()를 호출할 때 발생
        try {
            history.replaceState({}, '', 'https://www.example.com');
            console.log('URL changed successfully!');
        } catch (error) {
            console.error('Error occurred:', error.message);
        }
    }
</script>
</body>
</html>

위의 코드는 로컬에서 replaceState()를 호출하여 다른 origin의 URL로 변경하고자 할 때 에러가 발생할 수 있는 예제 코드다.
그러나 로컬 파일에서 실행되고 있기 때문에 보안상의 이유로 replaceState()의 호출이 실패하고 CORS 에러가 발생한다.


에러가 발생할 수 있는 유형

위의 에러 상황과 유사한 상황에 대해서 정리하였다.

브라우저 환경 설정
브라우저의 보안 설정이나 확장 프로그램이 replaceState() 호출을 차단할 수 있다. 브라우저 설정이나 확장 프로그램을 확인하고 필요한 경우 수정하거나 비활성화해야 한다.

브라우저 호환성
일부 예전 버전 또는 특정 버전의 브라우저에서는 replaceState()를 지원하지 않을 수 있으며, 이 경우에는 대안을 찾거나 폴리필(polyfill)을 사용하여 호환성을 보완해야 한다.

프로토콜 미일치
스크립트가 HTTP로 로드된 페이지에서 HTTPS로 로드된 페이지로 이동하거나 그 반대로 이동할 때 replaceState()를 호출하는 경우 에러가 발생할 수 있다. 이는 브라우저의 보안 정책으로 인해 HTTP와 HTTPS 간의 상태를 변경하는 것이 제한되기 때문이다.

크로스 프레임 제약
페이지가 다른 프레임이나 iframe에 포함되어 있고, 해당 프레임의 origin이 부모 페이지의 origin과 다를 경우에도 replaceState() 호출이 실패할 수 있다. 이는 보안상의 이유로 다른 origin 간에는 상태 변경을 제한하는 정책으로 인한 것이다.

보안 정책 및 권한 문제
브라우저의 보안 정책이나 사용자의 권한 설정에 따라 replaceState() 호출이 제한될 수 있다. 특정 사이트나 도메인에서는 스크립트가 history를 조작하는 것을 허용하지 않을 수 있다.



history.replaceState() 함수 사용 시 주의사항

위에서 예제를 통해 알아본 내용을 토대로 history.replaceState() 함수를 사용하려면 다양한 상황에 대해 고려를 해야 한다. 대부분이 보안 및 브라우저의 호환성 문제이며, 다시 한번 상세하게 정리해 보자.


보안 정책 및 권한 문제
브라우저의 보안 정책이나 사용자의 권한 설정에 따라 replaceState() 호출이 제한될 수 있으며, 특정 사이트나 도메인에서는 스크립트가 history를 조작하는 것을 허용하지 않을 수 있다.

프로토콜
스크립트가 HTTP로 로드된 페이지에서 HTTPS로 로드된 페이지로 이동하거나 그 반대로 이동할 때 replaceState() 함수를 호출하게 되면 에러가 발생할 수 있으며, 브라우저의 보안 정책으로 인해 두 프로토콜 간의 상태를 변경하는 것은 제한된다. 그렇기 때문에 대상 환경의 프로토콜이 일치하는지 확인하는 것이 중요하다.

크로스 프레임
replaceState()를 사용할 때 주의해야 할 점 중 하나는 페이지가 다른 프레임이나 iframe에 포함되어 있고, 해당 프레임의 origin이 부모 페이지의 origin과 다를 때다. 이런 경우에도 replaceState() 함수 호출이 실패할 수 있으며, 이는 브라우저의 보안 정책으로 다른 origin 간에는 상태 변경을 제한하는 것이다.

브라우저 호환성
replaceState() 함수는 예전 버전이나 특정 버전의 브라우저에서 지원하지 않을 수 있다.


이와 같이 거의 대부분은 브라우저의 정책, 보안에 대한 이슈로 replaceState() 함수를 사용하려면 반드시 이러한 부분들을 확인하는 것이 중요하다.

반응형

마무리

오늘은 자바스크립트 history.replaceState()의 에러 발생에 대한 내용을 주제로 정리해 봤다. 에러 내용은 간단했지만 생각보다 보안과 브라우저 정책 관련된 내용이 많았고, 로컬 환경에서 replaceState()를 사용하여 개발하려면 제약이 많다는 것을 알 수 있었다. 반드시 사용해야 되는 상황이라면 마지막에 정리한 주의사항을 살펴보고 작업 대상 환경에서 사용이 가능한지 확인을 해야 한다.


 

 

* javascript history replaceState() 기능 알아보기 

https://sancode.tistory.com/67

 

자바스크립트 히스토리 (history) 알아보기 !

안녕하세요. 오늘은 자바스크립트의 히스토리(history) 기능에 대해 정리해보려고 합니다. 히스토리 기능은 브라우저의 페이지를 다루는 기능이며, 서버 통신 없이 간단하게 페이지 전환이 가능

sancode.tistory.com

 

 

 


 

반응형