πŸ—žοΈ ν›ˆλ ¨μ†Œμ—μ„œ 맀일 λ‰΄μŠ€ 받아보기

고립된 ν›ˆλ ¨λ³‘μ„ μœ„ν•œ μ’…ν•© λ‰΄μŠ€

ν›ˆλ ¨μ†Œμ—μ„œ κ°€μž₯ λ‹΅λ‹΅ν•œ 것은 μ™ΈλΆ€μ™€μ˜ λ‹¨μ ˆμ΄λΌλŠ” 말을 자주 λ“€μ—ˆλ‹€. κ·Έλž˜μ„œ μž…λŒ€ν•œ μΉœκ΅¬λ“€μ—κ²Œ λ‰΄μŠ€λ‚˜ 읽을거리λ₯Ό μš”μ•½ν•΄μ„œ 인터넷 νŽΈμ§€λ‘œ 보내주곀 ν–ˆλŠ”λ°, 맀일 μ£Όμš” λ‰΄μŠ€λ₯Ό μš”μ•½ν•˜λŠ” 것은 μ˜μ™Έλ‘œ 손이 많이 κ°€λŠ” μΌμ΄μ—ˆλ‹€. 무엇보닀 인터넷 νŽΈμ§€ λ°œμ†‘μ„ μ§€μ›ν•˜λŠ” μ„œλΉ„μŠ€μΈ 더 μΊ ν”„μ˜ μΈν„°νŽ˜μ΄μŠ€κ°€ λ„ˆλ¬΄ λΆˆνŽΈν•΄μ„œ μ‚¬μš©ν•˜κΈ° 쉽지 μ•Šμ•˜λ‹€.

그러던 쀑 λ‚˜μ—κ²Œλ„ κ΅°μ‚¬κ΅μœ‘ μ†Œμ§‘ ν†΅μ§€μ„œκ°€ μ™”κ³ , 4μ£Όκ°„μ˜ 고립은 μ—­μ‹œ μ€‘λŒ€ν•œ λ¬Έμ œμ˜€λ‹€. κ·Έλ ‡κ²Œ μž…μ†Œλ₯Ό μ•žλ‘” μΌμš”μΌ, 맀일 인터넷 νŽΈμ§€λ‘œ λ‰΄μŠ€λ₯Ό λ³΄λ‚΄μ£ΌλŠ” ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€κ²Œ 됐닀.

더 μΊ ν”„ 라이브러리

ν›ˆλ ¨λ³‘μ—κ²Œ νŽΈμ§€λ₯Ό 보내렀면 λ°˜λ“œμ‹œ 더 μΊ ν”„λ₯Ό 거쳐야 ν•œλ‹€. 더 μΊ ν”„κ°€ μ˜€ν”ˆ APIλ₯Ό μ§€μ›ν•˜λ©΄ μ°Έ μ’‹κ² μ§€λ§Œ μ•ˆνƒ€κΉκ²Œλ„ 그렇지 μ•Šμ•˜λ‹€. κ²°κ΅­ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ HTTP μš”μ²­μ„ ꡬ성해 직접 더 μΊ ν”„ μ„œλ²„λ‘œ λ³΄λ‚΄λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν–ˆλ‹€.

ν”„λ‘œμ νŠΈ κ΅¬μ‘°λŠ” κ°„λ‹¨νžˆ κ³„νšν–ˆλ‹€. src 디렉토리 ν•˜μœ„μ˜ models 디렉토리에 각쒅 μΈν„°νŽ˜μ΄μŠ€λ₯Ό 두고, services λ””λ ‰ν† λ¦¬μ—λŠ” μ‹€μ œ μš”μ²­μ„ 보내고 값을 μ–»λŠ” ν•¨μˆ˜λ“€μ„ λͺ¨μ€λ‹€. utils λ””λ ‰ν† λ¦¬μ—λŠ” μ—¬λŸ¬ μ„œλΉ„μŠ€μ—μ„œ 반볡적으둜 μ‚¬μš©λ˜λŠ” ν•¨μˆ˜λ₯Ό λ‘κΈ°λ‘œ ν–ˆλ‹€.

.
+- examples 
+- src
|  +- models
|  +- services
|  +- utils
+- test

ꡬ체적으둜 μ–΄λ””λ‘œ μš”μ²­μ„ 보내야 ν•˜λŠ”μ§€ μ•Œμ•„λ‚΄κΈ° μœ„ν•΄ ν›ˆλ ¨μ†Œμ— μžˆλŠ” 지인(μ •ν™•νžˆλŠ” 친ꡬ의 학ꡐ ν›„λ°°μ˜€λ‹€.)μ—κ²Œ 인터넷 νŽΈμ§€λ₯Ό λ°œμ†‘ν•˜κ³  λΈŒλΌμš°μ €μ˜ 개발자 λ„κ΅¬μ—μ„œ λ„€νŠΈμ›Œν¬ 둜그λ₯Ό ν™•μΈν–ˆλ‹€.

개발자 도ꡬ λ„€νŠΈμ›Œν¬ νŒ¨λ„.

https://www.thecamp.or.kr/pcws/message/letter/insert.do에 μš”μ²­μ„ 보내면 λœλ‹€λŠ” 것을 μ•Œκ²Œ 됐닀. μš”μ²­ λ³Έλ¬Έμ—λŠ” unit_code, group_id λ“± μ•Œ 수 μ—†λŠ” 킀듀이 μžˆμ—ˆκ³ , 포슀트맨으둜 ν…ŒμŠ€νŠΈν•œ μš”μ²­μ—λŠ” 둜그인 정보λ₯Ό 찾을 수 μ—†λ‹€λŠ” 응닡이 λŒμ•„μ™”λ‹€.

λ‘œκ·ΈμΈμ— λŒ€ν•œ 응닡 헀더λ₯Ό μ‚΄νŽ΄λ³΄λ‹ˆ JSESSIONID와 SCOUTER μΏ ν‚€κ°€ μžˆμ—ˆλ‹€. HTTPλŠ” λ¬΄μƒνƒœ(Stateless) ν”„λ‘œν† μ½œμ΄κΈ° λ•Œλ¬Έμ— 독립적인 쌍의 μš”μ²­κ³Ό μ‘λ‹΅μœΌλ‘œ 연결이 λŠκΈ΄λ‹€.[1] λ‘œκ·ΈμΈν•œ μ‚¬μš©μžλ₯Ό μ‹λ³„ν•˜κΈ° μœ„ν•΄μ„œλŠ” μ„Έμ…˜ 정보λ₯Ό μœ μ§€ν•΄μ•Ό ν•˜λŠ”λ°, ν†°μΊ£ μ„œλ²„λŠ” 이λ₯Ό μœ„ν•΄ JSESSIONID와 SCOUTER μΏ ν‚€λ₯Ό μ‚¬μš©ν•œλ‹€. μΏ ν‚€λŠ” ν΄λΌμ΄μ–ΈνŠΈλ‹¨μ— μ €μž₯λ˜λŠ” 데이터이기 λ•Œλ¬Έμ— 값을 μœ μ§€ν•  수 있으며, μš”μ²­ 헀더에 μΏ ν‚€λ₯Ό ν¬ν•¨ν•˜λ©΄ μ„Έμ…˜μ„ μ‹λ³„ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€.

μ„œλ²„μΈ‘μ—μ„œ μš”μ²­μ„ λΉ„λ™κΈ°μ μœΌλ‘œ μ²˜λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— request-promiseλ₯Ό μ‚¬μš©ν•˜μ—¬ μ„Έμ…˜ μΏ ν‚€λ₯Ό μ–»μ–΄μ˜€λŠ” 둜그인 ν•¨μˆ˜λ₯Ό μž‘μ„±ν–ˆλ‹€. μ΄λ•ŒλŠ” λ‹¨μˆœν•˜κ²Œ μΏ ν‚€λ₯Ό λ°˜ν™˜ν•˜λŠ” 걸둜 λλƒˆλŠ”λ°, μ§€κΈˆ 생각해보면 μ„Έμ…˜ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°λ‘œ ν• λ‹Ήν•΄μ„œ λ‹€λ₯Έ μ„œλΉ„μŠ€μ—μ„œ λ°”λ‘œ μ‚¬μš©ν•˜λ„λ‘ λ§Œλ“€λ©΄ 더 νŽΈν–ˆμ„ 것 κ°™λ‹€.

interface Cookie {
  scouter: string;
  jsessionid: string;
}
async function login(id: string, password: string) {
  let result: Cookie | null = null;
  const options = {
    uri: buildRequestUrl('common/login.do'),
    method: 'POST',
    json: true,
    body: {
      'user-id': id,
      'user-pwd': password,
      subsType: 1,
    },
  };

  await requestPromise.post(options, (err, res, body) => {
    // ...
  });

  return result as Cookie;
}

μ΄μ–΄μ„œ μ‚¬μš©μžκ°€ κ°€μž…ν•œ 카페 μ€‘μ—μ„œ νŽΈμ§€λ₯Ό 받을 ν›ˆλ ¨λ³‘μ΄ μ†ν•œ 카페λ₯Ό μ°Ύμ•„μ•Όν•œλ‹€. λ§Œμ•½ ν›ˆλ ¨λ³‘μ΄ 25μ—°λŒ€ 5μ€‘λŒ€μ— μ†ν•΄μžˆλ‹€λ©΄ 더 μΊ ν”„μ—μ„œ 25μ—°λŒ€ 5μ€‘λŒ€ μΉ΄νŽ˜μ— κ°€μž…ν•˜κ³ , 이 μΉ΄νŽ˜μ—μ„œ νŽΈμ§€λ₯Ό λ³΄λ‚΄λŠ” 방식이닀.

카페 리슀트 μš”μ²­ 헀더λ₯Ό 톡해 μ•žμ„œ λ³Έ unit_code와 group_idλŠ” 각각 μ—°λŒ€/사단 식별 μ½”λ“œ, 카페 μ•„μ΄λ””λΌλŠ” 것을 μ•Œκ²Œ 됐닀. 그리고 μœ„μ™€ 같은 λ°©μ‹μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€μ™€ ν•¨μˆ˜λ₯Ό λ§Œλ“€μ—ˆλ‹€. 헀더에 둜그인으둜 얻은 μ„Έμ…˜ μΏ ν‚€λ₯Ό λ‹΄μ•„ μš”μ²­μ„ 보내면 μ‚¬μš©μžκ°€ κ°€μž…ν•œ 카페 리슀트λ₯Ό κ°€μ Έμ˜¨λ‹€. ν›ˆλ ¨λ³‘μ˜ μ†Œμ†κ³Ό μž…μ†Œ λ‚ μ§œλ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ£Όλ©΄ ν•΄λ‹Ή ν›ˆλ ¨λ³‘μ΄ μ†ν•œ 카페만 탐색해 λ°˜ν™˜ν•œλ‹€.

interface Group {
  unitName: string; // μ—°λŒ€/사단 이름
  fullName: string; // 카페 전체 이름
  enterDate: string; // ν›ˆλ ¨λ³‘ μž…μ†Œ λ‚ μ§œ (YYYYMMDD)
  groupId: string; // 카페 식별 μ½”λ“œ
  groupName: string; // 카페 이름
  groupImage: string; // 카페 λŒ€ν‘œ 이미지
  accessDate: string; // μš”μ²­ λ‚ μ§œ
  unitCode: string; // μ—°λŒ€/사단 식별 μ½”λ“œ
  unitType: number; // μœ‘κ΅°ν›ˆλ ¨μ†Œ(1)/μ‚¬λ‹¨μ‹ κ΅λŒ€(2) μ—¬λΆ€
  grade: number;
}
async function fetchGroups(cookies: Cookie, unitName?: string, enterDate?: string) {
  // ...
  return result as Group[];
}

응닡이 μŠ€λ„€μ΄ν¬ μΌ€μ΄μŠ€(snake_case)둜 λ–¨μ–΄μ§€μ§€λ§Œ μ½”λ“œμ˜ 캐멀 μΌ€μ΄μŠ€(camelCase)λ₯Ό ν¬κΈ°ν•˜κ³  싢지 μ•Šμ•˜λ‹€. λ•Œλ¬Έμ— 응닡을 μœ„ν•œ λ³„λ„μ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€μ—ˆλŠ”λ°, 손이 많이 κ°€μ§€λŠ” μ•Šμ§€λ§Œ μ†Œλͺ¨μ μΈ μΌμ΄μ—ˆλ‹€. λ­”κ°€ λ§€ν•‘ν•΄μ£ΌλŠ” 툴이 있으면 μ’‹κ² λ‹€λŠ” 생각이 λ“€μ—ˆλ‹€.

interface GroupResponse {
  unit_name: string;
  full_name: string;
  enter_date: string;
  group_id: string;
  group_name: string;
  group_image: string;
  access_date: string;
  unit_code: string;
  unit_type: number;
  grade: number;
}

μ‹€μ œ νŽΈμ§€ 전솑은 κ°„λ‹¨ν–ˆλ‹€. ν›ˆλ ¨λ³‘μ˜ 이름, 생년월일, ν›ˆλ ¨λ³‘κ³Όμ˜ 관계 정보와 ν•¨κ»˜ μ•žμ„œ 얻은 카페 정보듀을 λ‹΄μ•„ μš”μ²­μ„ 보내면 인터넷 νŽΈμ§€κ°€ λ°œμ†‘λλ‹€.

μ΄λ ‡κ²Œ the-camp-libλ₯Ό 'μ†ŒκΈ°μ˜ λͺ©μ  달성을 μœ„ν•œ μ΅œμ†Œν•œμ˜ μˆ˜μ€€β€™κΉŒμ§€ λ§Œλ“€μ–΄ npm νŒ¨ν‚€μ§€λ‘œ λ°°ν¬ν–ˆλ‹€.

ν›ˆλ ¨λ³‘μ„ μœ„ν•œ 데일리 λ‰΄μŠ€

인터넷 νŽΈμ§€ λ‚΄μš©μ€ λ‹€μŒλ‰΄μŠ€μ˜ RSSλ₯Ό μ΄μš©ν•΄ κ΅¬μ„±ν–ˆλ‹€. 인터넷 νŽΈμ§€μ˜ κΈ€μž μ œν•œμ΄ 2000자이기 λ•Œλ¬Έμ— μ΅œλŒ€ν•œ 경제적으둜 λ‚΄μš©μ„ ꡬ성해야 ν–ˆλ‹€. λ¨Όμ € κΈ°μ‚¬μ˜ 첫 λ¬Έμž₯만 μž˜λΌλƒˆλ‹€.

content = content.slice(0, content.indexOf('λ‹€.') + 1);

그리고 기사 μ•žμ— λΆ™λŠ” 바이라인과 λΆˆν•„μš”ν•œ 문ꡬλ₯Ό 지웠닀.

content = content.replace(/^(\*κ·Έλ¦Ό\d\*)?(\(|\[|【)\s?.*=.*\s?(\)|\]|】)\s?/, '')
  .replace(/^[κ°€-힣]{2,4}\s(기자|νŠΉνŒŒμ›)\s=\s/, '');

npm install the-camp-lib으둜 μ•žμ„œ λ§Œλ“  νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•˜κ³ , μ‹€μ œ νŽΈμ§€λ₯Ό λ³΄λ‚΄λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‹€.

async function setMessage() {
  // ...
}

(async () => {
  // ...

  const cookie = await thecamp.login(id, password);
  const [group] = await thecamp.fetchGroups(cookie, unitName, enterDate);
 
  const trainee = {
  
    traineeName,
    unitCode: group.unitCode,
    groupId: group.groupId,
    relationship: thecamp.Relationship.FATHER,
  };
 
  const date = new Date();
  const message = {
    title: `${date.getMonth()}μ›” ${date.getDate()}일 (${date.getHours()}μ‹œ ${date.getMinutes()}λΆ„) - λ‹€μŒλ‰΄μŠ€ μ’…ν•©`,
    content: (await setMessage()),
  };

  await thecamp.sendMessage(cookie, trainee, message);
})();

ν›ˆλ ¨λ³‘μ˜ μ΄λ¦„μ΄λ‚˜ 생년월일, μ†Œμ† λ“± ν›ˆλ ¨λ³‘μ— λŒ€ν•œ 사전 μ •λ³΄λŠ” .env νŒŒμΌμ„ μ΄μš©ν•΄ κ΄€λ¦¬ν–ˆλ‹€. μž…μ†Œ μ „μ—λŠ” μ†Œμ†μ„ μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ— μΉœκ΅¬μ—κ²Œ λ‚˜μ€‘μ— μ†Œμ†μ΄ λ‚˜μ˜€λ©΄ 값을 넣어달라고 뢀탁해뒀닀. νŽΈμ§€λ₯Ό λ³΄λ‚΄λŠ” 계정은 μ•„λ²„μ§€μ˜ 계정을 μ‚¬μš©ν–ˆλ‹€. λ‚΄κ°€ λ‚˜μ—κ²Œ νŽΈμ§€λ₯Ό 보내도 될 것 κ°™κΈ°λŠ” ν•˜μ§€λ§Œ, λ§Œμ— ν•˜λ‚˜ ν›ˆλ ¨μ†Œμ— λ“€μ–΄κ°€μ„œ λ¬Έμ œκ°€ 생기면 디버깅을 ν•  수 μ—†κΈ° λ•Œλ¬Έμ— μ΅œλŒ€ν•œ μ•ˆμ „ν•œ 방법을 택해야 ν–ˆλ‹€.

κ·Έλ ‡κ²Œ λ§Œλ“  νŒŒμΌμ„ 개인 μ„œλ²„μ— 올리고, 크둠(Cron)을 μ΄μš©ν•΄ ν•˜λ£¨ 두 λ²ˆμ”© νŒŒμΌμ„ μ‹€ν–‰ν•˜λ„λ‘ ν–ˆλ‹€.

0 0 * * * cd ~/projects/daily-news-for-trainee && ts-node index.ts
0 18 * * * cd ~/projects/daily-news-for-trainee && ts-node index.ts

νŽΈμ§€λ₯Ό 두 λ²ˆμ΄λ‚˜ 보낸 μ΄μœ λŠ” 더 λ§Žμ€ λ‰΄μŠ€λ₯Ό λ°›κΈ° μœ„ν•¨μ΄κΈ°λ„ ν•˜κ³ , ν•œ 번만 보내면 인편이 λˆ„λ½λ  수 μžˆλ‹€λŠ” 이야기λ₯Ό λ“€μ—ˆκΈ° λ•Œλ¬Έμ΄κΈ°λ„ ν•˜λ‹€. ν•˜ν•„ 0μ‹œ, 18μ‹œμΈ μ΄μœ λŠ” λ”±νžˆ μ—†μ—ˆλ‹€. λ‚˜μ€‘μ—μ•Ό μ•Œκ²Œ λμ§€λ§Œ, νŽΈμ§€λ₯Ό λ‚˜λˆ μ£ΌλŠ” μ‹œκ°„μ΄ λŒ€μ²΄λ‘œ 17μ‹œ μ „μ΄λΌμ„œ 18μ‹œλŠ” 쒋은 선택이 μ•„λ‹ˆμ—ˆλ‹€.

daily-news-for-traineeκΉŒμ§€ μ™„μ„±ν•˜λ©° ν›ˆλ ¨μ†Œμ— λ“€μ–΄κ°€κΈ° μ „ ν•  수 μžˆλŠ” 일은 λͺ¨λ‘ λλ§ˆμ³€λ‹€.

μ‹€ν–‰

8μ›” 29일 λ…Όμ‚° μœ‘κ΅°ν›ˆλ ¨μ†Œμ— μž…μ†Œν–ˆλ‹€. ν”„λ‘œκ·Έλž¨μ— λ¬Έμ œκ°€ μžˆμ–΄λ„ κ³ μΉ  수 μ—†λŠ” μƒν™©μ΄λ‹€λ³΄λ‹ˆ λ‰΄μŠ€κ°€ μ•ˆ 올까봐 λΆˆμ•ˆν•΄ν•˜λ©° 일주일을 λ³΄λƒˆλ‹€. 일주일 λ’€ 인사담당 ν›ˆλ ¨λ³‘λ“€μ΄ 인터넷 νŽΈμ§€λ₯Ό λ‚˜λˆ μ£ΌκΈ° μ‹œμž‘ν–ˆκ³ , μ„±κ³΅μ μœΌλ‘œ λ‰΄μŠ€κ°€ λ„μ°©ν–ˆλ‹€!

인터넷 νŽΈμ§€.

덕뢄에 맀일 두 톡씩 λ‰΄μŠ€λ₯Ό 받아보며 λ°”κΉ₯ μ†Œμ‹μ„ μ•Œ 수 μžˆμ—ˆλ‹€. μž…μ†Œ λ°”λ‘œ μ „λ‚  밀에 μ˜ˆμƒμΉ˜ λͺ»ν•œ λ¬Έμ œκ°€ μƒκ²¨μ„œ node_modules λ””λ ‰ν† λ¦¬μ˜ 트랜슀파일된 μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό 직접 μˆ˜μ •ν•˜λŠ” μ§“κΉŒμ§€ ν–ˆλŠ”λ°, λ‹€ν–‰νžˆ 잘 λ™μž‘ν–ˆλ‹€.

λͺ‡ 가지 μ‹€μˆ˜ν•œ 것이 μžˆλ‹€λ©΄ λ‚ μ§œκ°€ 0μ›”λΆ€ν„° μ‹œμž‘ν•΄μ„œ 제λͺ©μ˜ λ‚ μ§œκ°€ 9월이 μ•„λ‹ˆλΌ 8μ›”λ‘œ μ°ν˜€λ‚˜μ™”λ‹€λŠ” 점, λΆˆν•„μš”ν•œ 문ꡬλ₯Ό μ‚­μ œν•˜λŠ” μ •κ·œν‘œν˜„μ‹μ„ 잘λͺ» μž‘μ„±ν•˜μ—¬ κΈ°μ‚¬μ˜ μΌλΆ€κΉŒμ§€ λ‚ λ €λ²„λ¦¬λŠ” κ²½μš°κ°€ μžˆμ—ˆλ‹€λŠ” 점이닀.

λ˜ν•œ 일반적으둜 κΈ°μ‚¬μ˜ 첫 λ¬Έμž₯은 제λͺ©μ„ κ·ΈλŒ€λ‘œ λ°˜λ³΅ν•˜κΈ° λ•Œλ¬Έμ— 첫 λ¬Έμž₯을 λ³΄μ—¬μ£ΌλŠ”κ±΄ λ‚΄μš© νŒŒμ•…μ— 큰 도움이 λ˜μ§€ μ•Šμ•˜λ‹€. κ°€λ Ή β€œ14호 νƒœν’ β€˜κ°€μ§€ν‚€β€™ λ² νŠΈλ‚¨ λ‹€λ‚­μ„œ μ†Œλ©Έβ€ κΈ°μ‚¬μ˜ 첫 λ¬Έμž₯은 "λ² νŠΈλ‚¨ λ‹€λ‚­ λΆ€κ·Όμ—μ„œ λ°œμƒν•œ 제 14호 νƒœν’ '가지킀’가 μ—λ„ˆμ§€λ₯Ό μžƒκ³  μ†Œλ©Έλλ‹€"κ°€ λ˜λŠ” 식이닀. μ’…ν•© λ‰΄μŠ€λΌμ„œ 관심이 μ—†λŠ” λ‰΄μŠ€κ°€ λ§Žμ•˜λ˜ 것도 아쉬웠닀. μ„Ήμ…˜λ³„λ‘œ λ‰΄μŠ€λ₯Ό λ”°λ‘œ λ³΄λƒˆμœΌλ©΄ 더 μ’‹μ•˜μ„ 것 κ°™λ‹€. 우리 λΆ„λŒ€μ›λ“€μ€ 주둜 μ—°μ˜ˆ λ‰΄μŠ€λ₯Ό μ›ν–ˆλŠ”λ°, μ’…ν•©μ—λŠ” μ—°μ˜ˆ λ‰΄μŠ€κ°€ λ“€μ–΄κ°€λŠ” 일이 μ—†μ—ˆλ‹€.

κ²°μ •μ μœΌλ‘œ λ§€μΌμ˜€λŠ” λ‰΄μŠ€λ³΄λ‹€ μ‚¬λžŒμ΄ 보낸 νŽΈμ§€κ°€ 훨씬 μ’‹μ•˜λ‹€. νŽΈμ§€λ₯Ό λ°›μ•˜λŠ”λ° λ‰΄μŠ€λ©΄ 싀망감이 더 크닀.

κ·Έλž˜λ„ κ·Ήλ„λ‘œ μ œν•œμ μΈ ν™˜κ²½μ—μ„œ λ‚˜μ˜ 문제λ₯Ό ν•΄κ²°ν•΄λ³Έ κ²½ν—˜μ΄ κ½€ μž¬λ°Œμ—ˆλ‹€. κ°œλ°œν•  수 μžˆλŠ” μ‹œκ°„μ΄ λ§Žμ§€ μ•Šμ•„μ„œ 더 재밌던 것 같기도 ν•˜λ‹€. μ΄λ²ˆμ— 직접 μ°Ύμ•„λ‚Έ λ¬Έμ œλ“€μ„ κ°œμ„ ν•΄ λ‚˜μ€‘μ— μž…λŒ€ν•˜λŠ” μΉœκ΅¬μ—κ² 더 λ‚˜μ€ λ‰΄μŠ€λ₯Ό λ³΄λ‚΄μ€˜μ•Όκ² λ‹€.


  1. MDN web docs, β€œAn overview of HTTP”, 2019. β†©οΈŽ