사전 URI
포맷

URI

gabury1고친 사람 github-actions[bot]

URI 는 무언가를 한 줄의 글자로 가리키는 이름표입니다. 웹 페이지 주소가 가장 흔한 예입니다. 어떤 URI 는 가져오는 방법까지 알려 줍니다. 어떤 URI 는 이름 노릇만 합니다. 글자를 어떤 순서로 적는지는 모든 URI 가 같은 규칙을 따릅니다.

쉽고 빠른 이해

무슨 일을 하나 — 무언가를 글자 한 줄로 가리킵니다. https://shop.example.com/items/42 는 어느 서버의 어느 상품인지를 한 줄에 담습니다.

왜 필요한가 — 가리키는 방식이 프로그램마다 다르면 주고받을 수 없습니다. 모두가 같은 순서로 적으니 브라우저도 서버도 캐시도 같은 한 줄을 같은 대상으로 읽습니다.

어떻게 읽나

  1. 맨 앞의 https 같은 이름이 나머지를 어떻게 읽을지 정합니다
  2. // 뒤에 서버 이름이 옵니다. 그 뒤 / 로 이어진 경로가 서버 안의 대상을 고릅니다
  3. ? 뒤는 조건을 덧붙이고, # 뒤는 대상 안의 한 부분을 가리킵니다

대가 — 쓸 수 있는 글자가 정해져 있습니다. 한글이나 공백은 % 와 숫자로 바꿔 적어야 해서 사람이 읽기 어려워집니다.

상세

URI 는 Uniform Resource Identifier 의 줄임말입니다. 우리말로는 통합 자원 식별자입니다. 여기서 자원은 가리킬 수 있는 무엇이든입니다. 웹 페이지, 이미지 파일, 책 한 권, 메일 주소가 전부 자원이 될 수 있습니다.

글자를 적는 규칙은 RFC 3986 한 문서에 모여 있습니다. RFC(Request for Comments)는 인터넷 표준을 담는 문서 묶음입니다. 규칙이 한 곳에 있어서 브라우저와 서버와 라이브러리가 같은 줄을 같은 방식으로 쪼갭니다.

한 줄을 이루는 다섯 조각

URI 는 정해진 순서로 놓인 조각 다섯으로 읽힙니다. 스킴·authority·경로·쿼리 문자열·프래그먼트입니다. 이 소절은 상품 주소 하나를 쪼개서 각 조각이 하는 일을 봅니다.

authority 는 자원을 쥔 쪽을 적는 조각입니다. 대개 서버 이름과 포트가 여기에 들어갑니다. authority 는 안에서 다시 사용자 정보·호스트·포트 셋으로 나뉩니다. 아래 그림은 이 포함 관계를 보입니다.

flowchart TD
    U["URI 한 줄"] --> S["스킴"]
    U --> A
    U --> P["경로"]
    U --> Q["쿼리 문자열"]
    U --> F["프래그먼트"]
    subgraph A["authority"]
        I["사용자 정보"]
        H["호스트"]
        O["포트"]
    end

아래 표는 https://[email protected]:8443/items/42?color=red#reviews 를 쪼갠 것입니다. authority 는 셋으로 나눠 적어서 표는 일곱 줄입니다.

조각 앞뒤 표시 이 예의 값 하는 일
스킴 뒤에 : https 나머지를 어떻게 읽고 무엇으로 가져올지 정한다
사용자 정보 뒤에 @ kim 접속하는 사용자를 적는다. 거의 안 쓴다
호스트 // 뒤 shop.example.com 자원을 쥔 서버를 가리킨다
포트 앞에 : 8443 서버의 어느 문으로 들어갈지 정한다. 빠지면 스킴의 기본값을 쓴다
경로 / 로 시작 /items/42 서버 안에서 자원을 고른다
쿼리 문자열 앞에 ? color=red 경로로 고른 자원에 조건을 덧붙인다
프래그먼트 앞에 # reviews 가져온 자원 안의 한 부분을 가리킨다

표에서 반드시 있는 조각은 스킴과 경로뿐입니다. 경로는 비어 있어도 됩니다. mailto:[email protected] 에는 // 도 authority 도 없습니다. 스킴 뒤에 경로 하나만 붙은 URI 입니다.

프래그먼트는 다른 조각과 쓰임이 다릅니다. 웹 브라우저는 요청을 보낼 때 # 뒤를 서버에 보내지 않습니다. 자원을 받아 온 뒤 브라우저가 그 안에서 해당 부분을 찾아 화면을 옮깁니다.

가리키기만 하는 URI 와 찾아가는 URI

URI 가 늘 무언가를 가져오는 주소인 것은 아닙니다. 이름표로만 쓰일 때도 많습니다. 사람에 비유하면 주민등록번호는 그 사람이 누구인지만 알려 줍니다. 집 주소는 찾아가는 길까지 알려 줍니다.

찾아가는 길까지 담은 URI 를 URL(Uniform Resource Locator, 자원 위치 지정자)이라고 합니다. https:// 로 시작하는 주소가 그렇습니다. 스킴은 HTTP(HyperText Transfer Protocol)를 쓰라고 알려 줍니다. 호스트와 경로는 어디로 갈지 알려 줍니다.

이름만 담은 URI 는 URN(Uniform Resource Name, 자원 이름)이라고 부릅니다. urn:isbn:9780131103627 은 책 한 권을 가리킵니다. 그 책을 어디서 받는지는 말하지 않습니다.

실무에서는 URL 과 URI 를 섞어 부릅니다. 웹 주소 대부분이 둘 다에 해당해서 큰 문제가 없습니다. 다만 URI 가 URL 보다 넓은 이름입니다. 새로 쓰는 표준 문서들은 넓은 쪽인 URI 로 부릅니다.

이름으로만 쓰는 예 — XML 네임스페이스

이름표로만 쓰는 대표 사례가 XML(Extensible Markup Language, 확장 가능 마크업 언어)의 네임스페이스입니다. 네임스페이스는 이름이 겹치지 않게 붙이는 소속입니다. 두 회사가 모두 price 라는 태그를 써도 소속이 다르면 서로 다른 태그로 읽힙니다.

이 소속을 URI 로 적습니다. 안드로이드 설정 파일의 http://schemas.android.com/apk/res/android 가 한 예입니다. 이 줄은 http 로 시작하지만, XML 을 읽는 프로그램은 그 주소로 요청을 보내지 않습니다. 글자가 같은지만 비교합니다.

URI 를 이름으로 쓰는 까닭은 겹치지 않는 이름을 쉽게 만들 수 있어서입니다. 자기 도메인 이름을 앞에 붙이면 남과 겹칠 일이 거의 없습니다.

HTTP 에서 URI 가 하는 일 — 캐시의 열쇠

HTTP 요청은 언제나 URI 하나를 향합니다. 이 URI 가 대상 URI 입니다. 서버는 이 URI 로 어느 자원을 돌려줄지 고릅니다.

캐시도 이 URI 로 응답을 찾습니다. 같은 대상 URI 로 다시 요청이 오면 저장해 둔 응답을 꺼내 씁니다. 캐시가 저장한 응답을 다시 찾을 때 쓰는 기준값을 캐시 키라고 합니다.

캐시 키에는 대상 URI 가 반드시 들어갑니다. 요청 메서드도 함께 들어갑니다. 같은 URI 라도 메서드가 다르면 돌아오는 응답이 다를 수 있어서입니다.

URI 는 무효화의 단위이기도 합니다. POST 처럼 자원을 바꾸는 요청이 성공하면 캐시는 그 대상 URI 로 저장한 응답을 버립니다. 버리지 않으면 바뀌기 전의 낡은 응답을 계속 내주게 됩니다.

서버는 응답 헤더 Location 에 관련된 다른 자원의 URI 를 적어 보낼 때가 있습니다. 새로 만든 자원의 URI 가 대표적입니다. 그 URI 로 저장한 응답도 낡았을 수 있어서 캐시는 이것도 함께 버릴 수 있습니다.

다만 아무 URI 나 버리지는 않습니다. 스킴·호스트·포트 셋을 묶은 것을 오리진이라고 합니다. 캐시는 Location 의 오리진이 대상 URI 의 오리진과 같을 때만 버립니다. 응답 헤더는 서버가 마음대로 적을 수 있어서입니다. 이 제한이 없으면 한 서버가 Location 에 남의 사이트 URI 를 적어 그 사이트의 캐시까지 비울 수 있습니다.

쓸 수 없는 글자와 퍼센트 인코딩

URI 에 쓸 수 있는 글자는 영문자, 숫자, 몇 가지 기호뿐입니다. 이 범위는 ASCII(American Standard Code for Information Interchange) 안에 있습니다. 한글이나 공백은 그대로 넣을 수 없습니다.

넣을 수 없는 글자는 퍼센트 인코딩으로 바꿔 적습니다. 글자를 바이트로 바꾼 뒤, 바이트마다 % 와 16진수 두 자리로 적는 방식입니다. 한글은 먼저 UTF-8(Unicode Transformation Format 8-bit)로 바이트를 얻습니다.

공백    →  %20
한      →  %ED%95%9C

한 은 UTF-8 로 ED 95 9C 세 바이트입니다. 그래서 퍼센트 기호가 세 번 붙습니다. 공백은 한 바이트 20 이라 한 번만 붙습니다.

기호 가운데 / ? # : @ 은 조각을 가르는 표시로 쓰입니다. 이런 기호가 예약 문자입니다. 값 안에 이 기호가 들어가야 하면 역시 퍼센트 인코딩으로 바꿉니다. 쿼리 값에 # 을 그대로 두면 거기서 프래그먼트가 시작된 것으로 읽힙니다.

상대 참조 — 앞부분을 빼고 적기

HTML(HyperText Markup Language) 문서 안의 링크는 ../img/logo.png 처럼 앞부분 없이 적을 때가 많습니다. 이런 줄을 상대 참조라고 부릅니다. 스킴부터 다 적은 줄은 절대 URI 라고 부릅니다.

상대 참조는 혼자서는 무엇을 가리키는지 모릅니다. 기준 URI 를 하나 정하고, 거기에 붙여 절대 URI 로 바꿔야 합니다. 기준은 대개 그 링크가 들어 있는 문서의 URI 입니다.

아래는 기준이 http://a/b/c/d 일 때 각 줄이 바뀌는 결과입니다. // 뒤가 결과입니다.

g        // http://a/b/c/g
../g     // http://a/b/g
/g       // http://a/g
#s       // http://a/b/c/d#s

g 는 기준 경로의 마지막 토막 d 를 갈아 끼웁니다. ../g 는 한 단계 더 올라갑니다. / 로 시작하면 경로를 처음부터 새로 적은 것으로 읽습니다. #s 는 경로를 그대로 두고 기준 뒤에 프래그먼트만 붙입니다.

같은 URI 인가

글자가 다른데 같은 자원을 가리키는 URI 들이 있습니다. 스킴과 호스트는 대소문자를 가리지 않습니다. HTTPS://Shop.Example.com/ 과 https://shop.example.com/ 은 같은 곳입니다.

경로는 다릅니다. 경로의 대소문자를 가릴지는 서버가 정합니다. 그래서 일반적으로는 다른 URI 로 봅니다. /Items 와 /items 가 같은 자원이라고 미리 가정할 수 없습니다.

비교하기 전에 글자를 한 가지 꼴로 맞추는 일을 URI 정규화라고 합니다. 스킴과 호스트는 소문자로 맞춰도 같은 곳이라 안심하고 맞춥니다. 경로의 대소문자는 서버가 정하므로 건드리지 않습니다.

캐시가 스킴과 호스트를 맞추지 않으면 문제가 생깁니다. HTTPS://Shop.Example.com/ 과 https://shop.example.com/ 으로 온 요청을 다른 대상으로 봅니다. 같은 자원이 캐시에 두 번 저장됩니다.

관련 항목

URI 를 이루는 구성 요소

스킴 · authority · 호스트 · 포트 · 경로 · 쿼리 문자열 · 프래그먼트 · 사용자 정보

URI 의 하위 종류

URL · URN · 데이터 URI · 상대 참조 · 절대 URI

URI 와 이름이 헷갈리는 식별자

IRI · URL · UUID · 도메인 이름 · 경로명

URI 를 정의하는 표준 문서

RFC 3986 · RFC 3987 · RFC 8141 · WHATWG URL 표준

URI 에 글자를 담는 인코딩 규칙

퍼센트 인코딩 · 예약 문자 · ASCII · UTF-8 · 퓨니코드 · URI 정규화

URI 로 대상을 가리키는 프로토콜과 포맷

HTTP · XML · 네임스페이스 · HTML · REST · mailto

URI 를 열쇠로 쓰는 캐시 규칙

캐시 키 · 무효화 · 오리진 · 요청 대상 · Location · Content-Location

다른 이름: Uniform Resource Identifier · 통합 자원 식별자