URL과 URLSearchParams에 대한 관찰 [티]

eeensu·2025년 8월 26일

Javascript

목록 보기
41/41

둘다 모두 js에서 url 링크를 다룰 때 기본적으로 제공되어 사용하는 web api이다. 용도와 역할이 비슷하지만 다른 이 두가지에 대해 알아보자.

URL 클래스

  • 전체 URL을 분해하거나 조작할 수 있는 객체
  • 프로토콜, 호스트, 경로, 쿼리 무자열 등 URL의 모든 구성요소에 접근할 수 있음
  1. 기본 구조 분석
const url = new URL("https://example.com/page?search=apple&sort=asc");

console.log(url.protocol);  // "https:"
console.log(url.hostname);  // "example.com"
console.log(url.pathname);  // "/page"
console.log(url.search);    // "?search=apple&sort=asc"
console.log(url.hash);      // ""

참고로, url.toString()url.href 는 같은 값을 반환한다. 전자는 읽기 전용이고 후자는 읽고 쓰기가 가능하다는 차이가 있다.


  1. 동적 생성
    아래와 같이 동적으로 생성할 수 있다. api 엔드포인트를 조립할 때 유용하다.
const base = new URL("https://api.example.com/");
base.pathname += "products/1234";
base.searchParams.set("lang", "ko");

console.log(base.toString()); // "https://api.example.com/products/1234?lang=ko"

  1. 상대 경로에서 절대 URL 만들기
    SSR 환경이나 window.location.origin이 없는 환경에서 절대 경로 생성
const absoluteUrl = new URL("/images/logo.png", "https://example.com/");
console.log(absoluteUrl.href); // "https://example.com/images/logo.png"

  1. 현재 브라우저 URL 정보 가져오기
    페이지 라우팅이나 추적 이벤트 등에 활용할 수 있다.
const currentUrl = new URL(window.location.href);
console.log(currentUrl.pathname); // 예: "/products"



URLSearchParams 클래스

  • 오직 쿼리 문자열 (query stirng) 만 다루는 객체
  • URL 없이도 독립적으로 사용할 수 있고, ?key=value 구조의 문자열을 다루는데 특화되어있음

  1. 쿼리 파싱 및 조작
const params = new URLSearchParams("?search=baguette&sort=asc");

params.set("sort", "desc");
params.append("tag", "new");
params.delete("search");

console.log(params.toString()); // "sort=desc&tag=new"
// 객체 형태로도 생성 가능
const params = new URLSearchParams({
    mode: 'dark',
    page: '1',
    draft: 'false',
    sort: 'email',
})
params.append('sort', 'date') // email은 date로 변경됨

console.log(params.toString()) // mode=dark&page=1&draft=false&sort=email&sort=date

  1. 쿼리 파라미터 반복문 처리
    다중 선택이 가능한 필터를 통해 API 요청 쿼리 만들 때 유용하다.
const params = new URLSearchParams("a=1&a=2&b=3");

for (const [key, value] of params) {
  console.log(key, value);
}
// a 1
// a 2
// b 3

  1. 객체 <--> 쿼리 문자열 반환 유틸함수
    검색과 정렬, 필터링을 통해 데이터 리스트를 검색하여 api 경로를 만들어야 할때, 혹은 현재 api 경로를 파싱하여 선택된 각 key와 value을 사용해야할 때 좋다.
const objectToSearchParams = (obj: Record<string, any>) {
  return new URLSearchParams(obj).toString();
}

const searchParamsToObject = (search: string) => {
  const params = new URLSearchParams(search);
  return Object.fromEntries(params.entries());
}

console.log(objectToSearchParams({ page: 1, sort: "asc" }));
// "page=1&sort=asc"

console.log(searchParamsToObject("page=1&sort=asc"));
// { page: "1", sort: "asc" }

  1. REST api 를 사용하는 클라이언트 api에서 동적으로 경로를 만들어주는 함수
export const makeUrl = (path: string, query?: Record<string, string | number | undefined>) => {
  const url = new URL(path, "https://api.example.com");
  if (query) {
    Object.entries(query).forEach(([k, v]) => {
      if (v !== undefined) url.searchParams.set(k, String(v));
    });
  }
  return url.toString();
};

console.log(makeUrl("/products", { category: "bread", page: 2 }));
// "https://api.example.com/products?category=bread&page=2"

  1. append()set() 의 차이
    append() 는 기존 파라미터 키에 새로운 값을 추가하며, set()은 기존 값을 지워버리고 새로운 값을 추가함
const searchParams = new URLSearchParams();
searchParams.set("mode", "dark");
searchParams.set("page", 1);
searchParams.set("draft", false);
searchParams.set("sort", "email");
searchParams.set("sort", "date");
searchParams.toString(); // 'mode=dark&page=1&sort=date&draft=false'



URL과 URLSearchParams를 함께 사용

기존의 URL의 쿼리 스트링을 접근하거나 조작하고 싶을 때는 URL 과 함께 URLSearchParams를 쓰면 유용하다. URL 객체의 search 속성에는 쿼리 스트링이 문자열로 저장되어 있고, searchParams 속성에는 쿼리 스트링이 URLSearchParams 객체로 저장이 되어 있다.

const url = new URL("https://example.com/pokemon/post?q=pitchu");
url.search; // '?q=pitchu'
url.searchParams; // URLSearchParams {size: 1}

url.searchParams.get("q"); // 'pitchu'
url.searchParams.set("q", "updated");
url.searchParams.append("r", 1);
url.searchParams.append("r", false);

url.toString(); // 'https://example.com/pokemon/post?q=updated&r=1&r=false'

주의해야할 사항은, URL 객체의 `searchParams` 속성은 읽기 전용이기 때문에 새로운 `URLSearchParams` 객체로 대체할 수 없다.
const url = new URL("https://example.com/pokemon/post?q=pitchu");
url.searchParams = new URLSearchParams("q=updated&r=2&r=false");
url.toString(); // 'https://example.com/pokemon/post?q=pitch'

대신에 search 속성은 쓰기가 가능하기 때문에 아래와 같이 URLSearchParams 객체를 문자열로 변환한 후에 URL객체 search속성에 할당해주면 된다.

const url = new URL("https://example.com/pokemon/post?q=pitchu");
url.search = new URLSearchParams("q=updated&r=2&r=false").toString();
url.toString(); // 'https://example.com/pokemon/post?q=pitch'



요약하자면,

  • URL - 전체 URL 다루기
  • URLSearchParams - 쿼리 문자열만 다루기
  • 전체 URL에서 도메인, 경로, 쿼리 등 다양한 부분을 파악해야할 때 URL을 사용하고, 쿼리 문자열만 빠르게 파싱하거나 조작하고 싶을 때는 URLSearchParams 를 사용하면 된다.
profile
안녕하세요! 프론트엔드 개발자입니다! (2024/03 ~)

0개의 댓글