URL 객체


Untitled

현재 페이지의 URL이 아래와 같다고 가정했을 때... 참고로 %20 은 빈칸(space) 1개

<https://example.com/?name=Jonathan%20Smith&age=18>

url 객체의 search 속성을 이용해 모든 쿼리 스트링 내용을 가져올 수 있다

const url = new URL(window.location.href) // 현재 url 
url.search // '?name=Jonathan%20Smith&age=18'

name age 같은 특정 쿼리 스트링만 가져오고 싶다면 URLSearchParams 메서드를 이용하면 된다. get으로 값을 조회하고 append(기존 값에 이어붙이기) 혹은 set(기존값 교체)으로 새로운 값을 추가할 수도 있다.

url.searchParams.get('name') // 'Jonathan Smith'
url.searchParams.get('age') // 18

url.searchParams.append('city', 'Seoul') // 'city' 키 값에 'Seoul' 추가
url.searchParams.get('city') // 'Seoul'

url.searchParams.set('name', 'Johan') // 'name' 키 값을 'Jahan'으로 대체
url.searchParams.get('name') // 'Johan'

만약 특정 쿼리의(키) 값이 여러개라면 getAll을 이용해서 모두 조회할 수 있다. get은 첫번째 값만 가져온다

url.searchParams.set('name', 'Smith')
url.searchParams.append('name', 'Johan')
url.search // '?name=Smith&age=18&name=Johan'

url.searchParams.get('name') // 'Smith'
url.searchParams.getAll('name') // ['Smith', 'Johan']

toString 메서드를 사용하면 문자열 형태로 가져올 수 있다

const url = new URL('<https://example.com/?name=Jonathan%20Smith&age=18>')
url.toString() // '<https://example.com/?name=Jonathan%20Smith&age=18>'

searchParams 객체


searchParams 객체만 따로 만들어서 단독으로 조작할 수도 있다. 쿼리 스트링(url.search)을 제외한 다른 주소가 필요없을 때 사용하면 유용하다. 사용 방법은 URL 객체와 비슷하다.

const searchParams = new URLSearchParams('hello=world');
searchParams.get('hello') // 'world'
searchParams.append('name', 'Johan') // 'Johan'
searchParams.toString() // 'hello=world&name=Johan'

체크박스나 라디오 같은 form 양식을 전송할 때 application/x-www-form-urlencoded 콘텐츠 타입으로 보내야하는 경우가 있다. form 양식을 <form> 태그로 감싸고 <input type="submit" /> (혹은 submit 타입의 button 태그) 제출 버튼을 누르면 서버로 전송되는 방식이다(참고 링크).

<aside> 💡 button 타입의 기본값은 submit이다(form 데이터를 제출하는 버튼임을 명시).

</aside>

<form onSubmit={(e) => e.preventDefault()}>
  <div>
    <span>이메일</span>
    <input type="email" onChange={this.handleInputValue('email')} />
  </div>
  <button className="btn btn-login" type="submit" onClick={this.handleLogin}>
    로그인
  </button>
</form>;

만약 form 양식(input 태그)을 별도 상태로 관리하고, 제출 버튼이 있는 컴포넌트와 <input> 태그를 렌더하는 컴포넌트도 다르다면 searchParams 객체를 활용할 수 있다.

아래 코드에서 payload는 POST 요청 시 body로 보낼 데이터다. 이 데이터를 JSON으로 변환한 후 원하는 key의 값으로 담아서 보내면 된다. 아래 코드에선 'input'이라는 key에 담았다.

export default {
	get: () => {}, // 생략
  post: payload => {
    const params = new URLSearchParams();
    params.append('input', JSON.stringify(payload));

    return axios.post(`${baseUrl}/submit`, params, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    });
  },
};

배열 / 객체를 JSON으로 변환한 후 쿼리 스트링으로 할당하면 아래처럼 URL 인코딩(ASCII Encoding) 된다.

const url = new URL('<https://example.com/>');
const payload = [{ name: 'Johan', age: 30 }];

url.searchParams.append('input', JSON.stringify(payload));
url.search // '?input=%5B%7B%22name%22%3A%22Johan%22%2C%22age%22%3A30%7D%5D'

Untitled

더 많은 URL 인코딩 레퍼런스 리스트는 W3C 참고.

<aside> 💡 searchParams 객체는 forEach 메서드를 자체적으로 지원하고(value 순회) for of 반복문도 사용할 수 있다(key/value 쌍 순회). 유니코드 포인트 순으로 key를 정렬하는 sort() 메서드도 있다.

</aside>

const searchParams = new URLSearchParams()
searchParams.append('name', 'smith')
searchParams.append('name', 'johan')
searchParams.append('age', '30')

// 모든 value 순회
searchParams.forEach(el => console.log(el)); // 'smith' 'johan' '30'

// 모든 key/value 쌍 순회. searchParams.entries()를 순회하는 것과 동일하다
for (p of searchParams) {
  console.log(p) // ['name', 'smith'] ['name', 'johan'] ['age', '30']
}

// 모든 key 순회
for (key of searchParams.keys()) {
  console.log(key) // 'name' 'age'
}

// 모든 value 순회
for (key of searchParams.values()) {
  console.log(key) // 'smith' 'johan' '30'
}

const searchParams = new URLSearchParams("c=4&a=2&b=3&a=1");
searchParams.sort() // 유니코드 포인트 값에 따라 key 정렬 
console.log(searchParams.toString()); // "a=2&a=1&b=3&c=4"

레퍼런스


(HTML&DOM) URL과 URLSearchParams

URL - Web API | MDN

URLSearchParams - Web API | MDN