현재 페이지의 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 객체만 따로 만들어서 단독으로 조작할 수도 있다. 쿼리 스트링(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'
더 많은 URL 인코딩 레퍼런스 리스트는 W3C 참고.
[
: %5B
]
: %5D
{
: %7B
}
: %7D
"
: %22
<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"