26. url

// url
//  인터넷 주소를 쉽게 조작하도록 도와주는 모듈이다.
//  url 처리에는 크게 두 가지 방식이 있었다.
//      1. 노드 버전 7에 추가된 WHATWG(웹 표준을 정하는 단체 이름) 방식의 url
//      2. 예전부터 노드에서 사용하던 방식의 url
//  요즘은 WHATWG 방식만 사용한다.
//  브라우저에서도 WHATWG 방식을 사용하므로 호환성이 좋다.

// 노드가 자기 자신만의 방식이 있었다.
//  1. CommonJS
//  2. url

// 요즘은 위와 같은걸 없애고 웹 표준 방식으로 바꾸려하고 있다.
// 한가지로 통일되면 클라이언트 개발, 서버 개발 서로 헷갈리지 않을 것이다.

// ------------------------------------------------------------
// href: https://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash
//  protocol: https
//  origin: https://
//  -----------------------
//  user: username
//  pass: password
//  -----------------------
//  hostname: sub.host.com
//  port: 8080
//  host: sub.host.com:8080
//  origin: sub.host.com:8080
//  -----------------------
//  pathname: /p/a/t/h
//  search: ?query=string
//  querystring: ?query=string
//  hash: #hash // <- 이 부분은 서버는 인식을 못하고 브라우저만 인식할 수 있는 부분이다.
//      그래서 주소를 보낼 때, 이 hash 부분을 보내도 의미가 없긴 하다.
//      브라우저만 인식하기 때문에, 이 hash 값을 달리해서보내면 미리 cache된 파일이 있다고 하더라도, 브라우저에서 다른 파일로 인식, 서버로 요청보내 다시 받아오기 때문에, 그런 용도로 사용된다.
//      보통은 querystring, path 에 정보를 넣어서 보낸다고 생각하면된다.

// username, password 는 처음 본 사람도 있을 것이다.
//  ex) https://hyungju12:****@naver.com:443/login?hello=world
//  원래는 위와 같이 id, pw를 넣을 수 있다.
//  네이버가 위와 같은 방식을 허용했는지 안했는지는 모르겠지만, 원래는 주소 앞에 id, pw 입력 자리가 마련되어있다.
//  물론 생략도 가능하다.

// 아래 코드를 작성하지 않아도 된다.
// url 은 노드 내장객체라서 아래 코드 없이도 실행 가능하다.
// const url = require('url');
// const {URL} = url;

const myURL = new URL('https://hyungju-lee.github.io/hyungju-lee2022.github.io/')
console.log(myURL);
// {
//   href: 'https://hyungju-lee.github.io/hyungju-lee2022.github.io/',
//   origin: 'https://hyungju-lee.github.io',
//   protocol: 'https:',
//   username: '',
//   password: '',
//   host: 'hyungju-lee.github.io',
//   hostname: 'hyungju-lee.github.io',
//   port: '',
//   pathname: '/hyungju-lee2022.github.io/',
//   search: '',
//   searchParams: URLSearchParams {},
//   hash: ''
// }
// console.log(url.format(myURL)); // https://hyungju-lee.github.io/hyungju-lee2022.github.io/
// format 메서드는 곧 deprecate 예정이다.

// 위 format 메서드를 대체하는 방법이다.
console.log(myURL.href); // https://hyungju-lee.github.io/hyungju-lee2022.github.io/
console.log(myURL.origin); // https://hyungju-lee.github.io
console.log(myURL.protocol); // https:
console.log(myURL.username); //
console.log(myURL.password); //
console.log(myURL.host); // hyungju-lee.github.io
console.log(myURL.hostname); // hyungju-lee.github.io
console.log(myURL.port); //
console.log(myURL.pathname); // /hyungju-lee2022.github.io/
console.log(myURL.search); //
console.log(myURL.searchParams); // URLSearchParams {}
console.log(myURL.hash); //

// --------------------------------------------------------------------------------------------------
const myURL2 = new URL('https://www.gilbut.co.kr/?page=3&limit=10&category=nodejs&category=javascript');
console.log(myURL2.searchParams);
// URLSearchParams {
//   'page' => '3',
//   'limit' => '10',
//   'category' => 'nodejs',
//   'category' => 'javascript' }

// 위에 보면 ?category=nodejs&category=javascript 이렇게 들어가있다.
//  같은 key가 2번 이상 사용되어있고, 각 부여된 값도 다르다. 뭔가 이상하다.
//  사실 이는 객체 개념상 말이 안된다.
//  { category: 'nodejs', category: 'javascript' }
//  같은 key에 2개의 값을 가질 수 없기 때문이다.
//  그런데 searchParams에서 위와 같이 key가 겹치는 경우는 값을 ['nodejs', 'javascript'] 이렇게 배열 형태로 만들어준다.
//  그래서 아래에 보면 같은 key에 append를 2번 이상 할 수 있는 것이다.

console.log(myURL2.searchParams.getAll('category')); // [ 'nodejs', 'javascript' ]
console.log(myURL2.searchParams.get('limit')); // 10
console.log(myURL2.searchParams.has('page')); // true
console.log(myURL2.searchParams.keys()); // URLSearchParams Iterator { 'page', 'limit', 'category', 'category' }
console.log(myURL2.searchParams.values()); // URLSearchParams Iterator { '3', '10', 'nodejs', 'javascript' }

myURL2.searchParams.append('filter', 'es3');
myURL2.searchParams.append('filter', 'es5');
console.log(myURL2.searchParams.getAll('filter')); // [ 'es3', 'es5' ]

myURL2.searchParams.set('filter', 'es6');
console.log(myURL2.searchParams.getAll('filter')); // [ 'es6' ]

myURL2.searchParams.delete('filter');
console.log(myURL2.searchParams.getAll('filter')); // []

console.log(myURL2.searchParams.toString()); // page=3&limit=10&category=nodejs&category=javascript
console.log(myURL2.search); // ?page=3&limit=10&category=nodejs&category=javascript

// Iterator
//  배열처럼 반복 작업을 쉽게해주는 객체이다.
//  URLSearchParams 는 Iterator 객체다.