JavaScript에서 URL을 파싱하는 방법: URL API vs 수동 파싱

발행: (2026년 5월 2일 PM 07:33 GMT+9)
5 분 소요
원문: Dev.to

I’m happy to translate the article for you, but I need the actual text you’d like translated. Could you please paste the content (or the portions you want translated) here? I’ll keep the source link at the top and preserve all formatting, code blocks, URLs, and technical terms as you requested.

URL 클래스 사용하기

const url = new URL('https://example.com:8080/path/page?q=hello+world&lang=en#section');

url.protocol; // "https:"
url.hostname; // "example.com"
url.port;     // "8080"
url.host;     // "example.com:8080"
url.pathname; // "/path/page"
url.search;   // "?q=hello+world&lang=en"
url.hash;     // "#section"
url.origin;   // "https://example.com:8080"
url.href;     // 전체 URL 문자열

파서는 엣지 케이스를 자동으로 처리합니다. 표준 포트는 host에서 생략됩니다:

new URL('http://example.com:80/').host; // "example.com"

URLSearchParams를 사용한 쿼리 파라미터

절대로 &=를 직접 분리하지 마세요—값에 인코딩된 &= 문자가 포함될 수 있습니다. 대신 URLSearchParams를 사용하세요:

const url = new URL('https://example.com?q=hello+world&tags=js&tags=css');
const params = url.searchParams;

params.get('q');        // "hello world" (decodes `+` as space)
params.getAll('tags'); // ["js", "css"]
params.has('tags');    // true

// Iterate all params
for (const [key, value] of params) {
  console.log(key, value);
}
// q hello world
// tags js
// tags css

쿼리 문자열 만들기

const params = new URLSearchParams({
  q: 'hello world',
  sort: 'date',
  page: '1'
});
params.toString(); // "q=hello+world&sort=date&page=1"

교체 없이 추가하기

params.append('tags', 'javascript');
params.append('tags', 'css');
params.toString(); // "q=hello+world&sort=date&page=1&tags=javascript&tags=css"

기존 URL 수정하기

const url = new URL('https://example.com?page=1&sort=date');

url.searchParams.set('page', '2');   // update
url.searchParams.delete('sort');    // remove
url.searchParams.append('filter', 'active'); // add

url.href; // "https://example.com/?page=2&filter=active"

상대 URL 해결

new URL('/about', 'https://example.com').href;
// "https://example.com/about"

new URL('../images/photo.jpg', 'https://example.com/blog/post/').href;
// "https://example.com/blog/images/photo.jpg"

new URL('?page=2', 'https://example.com/articles').href;
// "https://example.com/articles?page=2"

스크래핑이나 크롤러를 만들 때 상대 링크를 해석하는 올바른 방법입니다.

퍼센트‑인코딩 자동 수행

const url = new URL('https://example.com/search');
url.searchParams.set('q', 'café & creme brûlée');
url.href;
// "https://example.com/search?q=caf%C3%A9+%26+creme+br%C3%BBl%C3%A9e"

수동 인코딩/디코딩

// Encode a component value (e.g., query parameter value)
encodeURIComponent('hello world & more');
// "hello%20world%20%26%20more"

// Encode a full URL (preserves :, /, ?, =, &, #, @)
encodeURI('https://example.com/path?q=hello world');
// "https://example.com/path?q=hello%20world"

// Decode
decodeURIComponent('hello%20world');
// "hello world"

URL 검증

function isValidUrl(string) {
  try {
    new URL(string);
    return true;
  } catch {
    return false;
  }
}

isValidUrl('https://example.com'); // true
isValidUrl('not a url');           // false
isValidUrl('//example.com');       // true (protocol‑relative)

특정 프로토콜을 요구해야 하는 경우:

function isHttpUrl(string) {
  try {
    const url = new URL(string);
    return url.protocol === 'http:' || url.protocol === 'https:';
  } catch {
    return false;
  }
}

호스트명 vs. 호스트

new URL('https://sub.example.co.uk/path').hostname;
// "sub.example.co.uk"

new URL('https://example.com:443/path').host;     // "example.com:443"
new URL('https://example.com:443/path').hostname; // "example.com"

hostname은 포트를 제거하고, host는 포트를 포함합니다.

Node.js 호환성

URL 클래스는 Node.js v10부터 전역으로 사용할 수 있습니다. 이전 버전에서는:

const { URL, URLSearchParams } = require('url');

브라우저의 Web Workers와 Service Workers에서도 사용할 수 있습니다.

레거시 <a> 요소 트릭 (브라우저 전용)

URL API가 나오기 전, 개발자들은 DOM <a> 요소를 사용해 URL을 파싱했습니다:

const a = document.createElement('a');
a.href = 'https://example.com/path';
a.hostname; // "example.com"

이 방법은 브라우저에서만 동작하며, 엣지 케이스에 따라 브라우저마다 일관되지 않을 수 있고, URLSearchParams를 지원하지 않습니다. 최신 URL API를 사용하는 것이 권장됩니다.

결론

URL API와 URLSearchParams를 함께 사용하면 쿼리‑스트링 처리 및 엣지‑케이스 URL 파싱과 관련된 전체 버그 범주를 제거할 수 있습니다. 아직도 ?&를 수동으로 분할하고 있다면, API로 전환하세요—그때까지 URL을 어떻게 파싱했는지 궁금해질 겁니다.

0 조회
Back to Blog

관련 글

더 보기 »

Rails와 Webpacker로 ReactJS 구성

필수 조건 - Ruby 2.5.1 이상 - Rails 5.2.1 이상 - Webpacker 3.5.5 이상 Webpacker를 사용하여 새로운 Rails 앱 만들기 bash rails new rails-with-reactj...