URI 프래그먼트는 웹 콘텐츠와 상호작용하고 탐색하는 데 중요한 역할을 한다. 이 문서에서는 URI 프래그먼트가 무엇이며, 어떻게 작동하며, 웹 개발에서의 실용적인 함의에 대해 살펴보고자 한다.
https://example.com/page#section
에서 #section
은 페이지의 특정 섹션을 가리키는 URI 프래그먼트다.<div id="section">...</div>
또는 <a name="section">...</a>
은 #section
프래그먼트의 대상 요소가 됩니다.<h2>
요소의 id='examples'
과 네이게이션 요소의 href='#examples'
이 같은 값을 공유하는 것을 확인할 수 있다.프래그먼트 URL을 HTTP 요청 메시지로 보낼 때, 프래그먼트를 제외한 주소만 전송이 된다. 그 이유는 프래그먼트 식별자는 오직 브라우저에서만 사용되기 때문이다. 따라서, 프래그먼트는 서버에서 반환되는 리소스에 영향을 주지 않는다.
URL 상에서 #
기호가 호스트 이름, 경로 또는 쿼리 문자열 내, 어디든지 포함되어 있어도 상관없이 이는 항상 프래그먼트 식별자가 시작하는 위치를 나타낸다.
예를 들어, 다음은 HTML 색상과 모양을 쿼리 문자열로 인코딩하려는 URL이다:
http://example.com/?color=#ffff&shape=circle
color=#ffffff
는 색상 헥스 코드로 위의 쿼리문이 틀리지 않아 보인다. 불행히도 헥스코드의 #
기호는 URL의 나머지 부분을 프래그먼트 식별자로 만들어 버린다. 그리고, 서버는 쿼리 문자열에서 텅 비어 있는 color 매개변수만 볼 것이다:
프래그먼트는 몇 가지 편리한 기능을 가지고 있다. 먼저, 프래그먼트 URL을 수동으로 변경하면 다음과 같이 된다:
위 URL의 https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web#urls_and_urns
프래그먼트를 수동으로 아래와 같이 변경할 수 있다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web#examples
그러면 브라우저는 페이지를 새 위치로 스크롤하지만 페이지를 다시로드하지 않는다.
그러나 뒤로 가기 버튼을 클릭하면 페이지의 원래 위치로 돌아간다. 이는 브라우저의 히스토리에 항목이 추가되었기 때문이다.
이러한 기능은 특히 JavaScript와 함께 사용할 때 유용하다. 특히 링크 가능한 URL들을 생성하고, 페이지가 상위 수준의 HTML 프레임을 사용하거나 Ajax 호출로 콘텐츠를 동적으로 업데이트하는 경우에 히스토리를 생성하는 데 사용된다.
window 객체의 hash 속성을 사용하면 JavaScript가 현재 페이지의 프래그먼트 식별자를 조작할 수 있다. 위에서 설명한대로 이를 사용하여 페이지에 완전한 새로고침을 강제하지 않고도 히스토리 항목을 추가할 수 있다.
기존에는 콘텐츠가 브라우저에서 쉽게 접근할 수 있었지만, 관심 있는 주제 사이를 이동할 때 위치 표시줄의 URL이 변경되지 않았기 때문에 실제로 관심 있는 주제의 URL을 공유하는 것이 거의 불가능했다.
하지만, 프래그먼트 식별자와 JavaScript를 사용하여 링크 가능한 URL을 만드는 방식으로 이를 해결할 수 있다.
<a id="myAnchor" href="/en-US/docs/Location.href#Examples">Examples</a>
<script>
const anchor = document.getElementById("myAnchor");
console.log(anchor.hash); // Returns '#Examples'
anchor.hash = 'example-of-location';
console.log(anchor.hash); // Returns '#example-of-location'
</script>
Googlebot은 콘텐츠를 찾아 Google 검색 인덱스의 일부가 될 내용과 포함된 링크를 찾기 위해 사이트를 크롤링하는 역할을 한다. Googlebot은 HTML을 가져와 파싱하지만, 이는 완전한 브라우저가 아니며 JavaScript 엔진또한 없다. 따라서 보통 프래그먼트 식별자를 무시하고 웹 서버에서 반환된 리소스만을 살펴본다. 페이지를 로드하거나 컨텐츠를 구축하는데 사용된 JavaScript는 실행되지 않는다.
즉, Ajax 기반 사이트에서 색인을 생성하고 해당 프래그먼트 URL을 Google 검색에서 직접 반환하는 것은 불가능하다. 이 문제를 해결하기 위해 Google은 Google봇이 프래그먼트 식별자를 쿼리 문자열 매개변수로 변환할 수 있는 규칙을 지원한다.
이 인덱싱 체계를 사용하려면 먼저 모든 조각 식별자를 ! 기호로 시작하도록 변경해야 한다:
http://www.example.com/ajax.html#mystate
이와 같은 URL을 다음과 같이 변경한다:
http://www.example.com/ajax.html#!mystate
앞부분에 !기호가 있음으로 인해, 구글봇에게 프래그먼트 식별자가 있음을 알리는 것이다.
또한 페이지는 쿼리 문자열 매개변수에 대한 응답으로 특정 상태의, _escaped_fragment_
이라는 이름을 가지는, HTML 을 제공할 수 있어야 한다. Googlebot이 특정 상태의 콘텐츠가 필요할 때는 간단한 GET 요청과 쿼리 문자열 값을 사용하여 프래그먼트 식별자를 제공한다:
http://www.example.com/ajax.html?_escaped_fragment_=mystate
#
)에 링크하여, 문서 최상단으로 스크롤하는 기능을 구현할 수 있다.URI 프래그먼트는 웹 개발에서 정밀한 탐색과 상호작용을 가능케 하는 강력한 도구다. 프래그먼트가 작동하는 방식을 이해하고 최상의 방법을 적용함으로써 개발자는 더 직관적이고 사용자 친화적인 웹 경험을 제공할 수 있다. 단순한 웹 사이트든 복잡한 웹 애플리케이션이든, URI 프래그먼트를 마스터하는 것은 원활한 사용자 경험을 제공하기 위해 필수적이다.
적어주신 색상 예시처럼 쿼리 파라미터에 #을 넣어야 한다면 어떻게 escape 처리를 할 수 있을까요?