728x90
728x90

TIMELINE


5:00am  
6:00am  
7:00am  
8:00am  
9:00am  
10:00am  
11:00am 기상/ 계획/ 잠깨기
12:00pm 노드 js 문법/ 개념공부스터디룸 (공유오피스 상담)
1:00pm 점심식사
2:00pm 노드 js 문법 공부
3:00pm 스터디룸(공유오피스) 상담/ 노드 js 문법 공부
4:00pm 노드 js 문법 공부
5:00pm 딥다이브 -> 백앤드서버 구축하기
6:00pm 딥다이브 -> 프로그래머스
7:00pm 딥다이브 -> 프로그래머스
8:00pm 딥다이브 -> 프로그래머스
9:00pm 노드 js 문법 공부 -> til
10:00pm 노드 js 문법 공부 -> 집가기
11:00pm 노드 js 문법 공부 -> 잠
12:00am 티스토리업데이트 하기 -> 잠
1:00am  
2:00am  
3:00am  
4:00am  
5:00am  

오늘의 todo list
요즘 하고있는 것들



1. 자바스크립트 문법, 초심부터


https://insidepixce.tistory.com/106

 

[자바스크립트 문법 뽀개기] 1-3강 : hello world

초심으로 돌아가서 문법 뽀개기부터 하나하나 다시 볼 예정 ! 1주차 1-3 hello world 툴팁 console.log를 입력할떄 con…까지만 입력해도 뒤에 sole.log가 자동적으로 나온다 이를 툴팁이라고 한다. → 나는

insidepixce.tistory.com

https://insidepixce.tistory.com/107

 

[자바스크립트 문법 뽀개기] 1-4강 : 변수

변수 변수란? 저장해놓은 데이터, 값을 가리키는 일종의 이름표 자바스크립트에서는 변수를 선언할 때 let, const, var 키워드를 사용한다. let name = "ramona" const place = "seoul" console.log ("안녕". place , nam

insidepixce.tistory.com

 

https://insidepixce.tistory.com/108

 

[자바스크립트 문법 뽀개기] 1-5강 데이터 타입

1-6 데이터 타입 오늘 배울 타입 : 원시형 (primitive) → number, string, boolean , null,. undifined number: 숫자 string: 문자 boolean : 참/거짓 (true/false) null : 존재여부 undifined : 찾을 수 없다 💡 이러한 데이터들

insidepixce.tistory.com

아는 내용이 대다수였지만, 그 사이에서 얻는 내용도 많았던 강의들이였다.

항해 99를 진행할때 아는 거니까 ~ 하고 넘겼던 부분들을 내 언어로 풀어보니 어려운 감이 없지않아 있었다


2. 소감

 


정신적으로 신체적으로 참 많이 힘든 하루였다. 

물론 오후 되면서 짱 괜찮아지기는 했지만,,,

이제는 더이상 이런 일이 없었으면 좋겠다 !

나도 말 예쁘게 해야지 

728x90
300x250
728x90
728x90

1-6 데이터 타입


오늘 배울 타입 : 원시형 (primitive)

→ number, string, boolean , null,. undifined


number: 숫자

string: 문자

boolean : 참/거짓 (true/false)

null : 존재여부

undifined : 찾을 수 없다


<aside> 💡 이러한 데이터들은 왜 존재할까?

</aside>

→ 수많은 데이터들 속에서 컴퓨터가 보다 빠르고 효율적으로 처리하기 위해… 라고 교안에 나와있었다. 맞는 말이다.

→ 개인적인 생각을 서술해보자면,

데이터를 구분하여 처리 방식을 달리하기 위해

	100, True, ten

여기 이렇게 세 가지의 데이터가 있다고 하자.

각각의 타입을 한번 말해보라고 질문한다면,

분명히 평범한 사람들~~(님들처럼 개발에 미쳐있는 사람들 말고요)~~ 은 100은 숫자, true는 참과 거짓, ten 은 문자열이라고 답할 것이다.

이 문제에 뭐라고 답변을 하였건, 어떠한 타입을 말했다면 정답은 없다.

정답은 바로 “사용자가 어떻게 지정하느냐에 따라 다르겠지요? “ 이다.

나는 100을 문자열로 받을 수도 있고, True 또한 문자열로 받을 수 있다. ten은 문자열밖에 못 되겠지만, 앞 두 데이터는 다르게 될 수 있다는 것이다.

문제는 여기서 발생한다.


자바스크립트에서 변수의 타입은 동적으로 결정되므로, 굳이 파이썬마냥

a= string(300) 

이런 짓을 안 해줘도 된다.

변수에 할당되는 값에 따라 자동으로 타입이 지정된다

const ramonaage = 21;
const baskinrobbinsnname = '31';

이 경우에 내 나이인 ramonaage= 21로 숫자 타입이 되고, baskinrobbinsname 은 ‘31’로 스트링 타입이 된걸 볼 수 있다.

이때 실험을 해보자 .

const ramonaage = 21;
const baskinrobbinsnname = '31';

console.log(ramonaage + 3);
console.log(ramonaage + '3');
console.log(baskinrobbinsnname + '3');
console.log(baskinrobbinsnname + 3);

아까 말했듯 , ramonaage 는 숫자 타입이고 , baskinrobbinsnname 은 문자열 타입이다.

첫번째 console.log 에서는 숫자 타입에다 숫자 3을 더했고, 두번째에는 문자 3을 더했다.

세번째는 문자 31에 문자 3을 더했고, 네번째는 문자 31에 숫자3을 더했다.

 

 

출력결과

 

숫자 + 숫자 = 연산한다

숫자 + 문자 = 그냥 뒤에 갖다붙인다

문자 + 문자 = 그냥 뒤에 갖다붙인다

문자 + 숫자 = 뒤에 있는 숫자를 문자로 변형시켜 갖다붙인다

 

 

파이썬언어의 에로 들자면 4번째에서는 오류를 띄운다. 그런데 아까도 말했듯 자바스크립트의 문자열 타입은 동적으로 결정되므로 오류를 띄우지 않기 위해 뒤의 숫자를 문자로 변형시키는 것으로 보인다.

아무튼 사용자가 의도대로 (연산을 하던가, 문자 뒤에 숫자를 붙이거나) 원하는 작업을 할 수 있게 타입을 구분해 주는 것이다.

728x90
300x250
728x90
728x90

변수


변수란?

저장해놓은 데이터, 값을 가리키는 일종의 이름표

자바스크립트에서는 변수를 선언할 때 let, const, var 키워드를 사용한다.

let name = "ramona"
const place = "seoul"

console.log ("안녕". place , name, "이 왔다!")

이런 출력값이 나온다.

지난 시간 출력할때 console.log() 를 배웠는데, 원래는 출력할 내용 전부를 입력해야 했다.

그렇지만, 이번에는 변수 이름만 입력해도 된다 !

니다. let과 const는 블록 스코프 변수를 선언하는데 사용되며, var는 함수 스코프 변수를 선언하는데 사용됩니다. 변수를 선언할 때는 변수명을 지정하고, 이후에 = 기호를 사용하여 변수에 값을 할당할 수 있습니다.

  • let : 한번 변수에 값을 할당하고 나서도 다시 바꿀 수 있다
let name = "ramona"
console.log(name);

name = "william"
console.log(name)

처음에 ramona 로 변수를 설정해주었는데, 뒤에는 william 으로 재할당을 해주었다

ramona에서 william으로 Name 변수에 할당된 값이 바뀌었다는 것을 알 수 있다.\

 

  • const : let과 달리 변수에 재할당을 하지 않을 떄 사용
const name =  "killing in the name"
console.log(name)
const name = "killing in my name"
name = "killing all the name"›

이게 과연 동작할까?

벌써부터 빨간줄이 가득가득한 걸 볼 수 있다.

const 를 두번 한 것 자체도 문제고, const name 후 다시 name을 지정해주는것도

여기 딱 보면,,, 딱 적혀있다

변수 name은 이미 선언되었습니다! 라고 이렇게 막아버리는 걸 볼 수 있음 !

var은… 인기 없음 걍 넘겨

 

728x90
300x250
728x90
728x90

초심으로 돌아가서 문법 뽀개기부터 하나하나 다시 볼 예정 !


1주차 1-3 hello world


  • 툴팁

console.log를 입력할떄 con…까지만 입력해도 뒤에 sole.log가 자동적으로 나온다

이를 툴팁이라고 한다.

→ 나는 깃 코파일럿을 쓰고 있어서 더 나온다 . 딱히 상관없음 .

  • 그럼 도대체 ``console.log()` 가 뭔데?

원하는 문구를 출력하는 법

console.log("나다 세상아!" )

이 경우에는 console.log 안에 있는 “나다 세상아” 문구가 출력된다.

자바스크립트에서 문자열로 설정하기 위해서는 ‘ ‘ 혹은 “ “ 즉 작은 따옴표, 큰 따옴표로 둘러쌓여 있다.

  • 저장하기

여기 보면 파일명 옆에 동그라미가 있다

이 동그라미는 저장이 안되어있어서 생기는 것.

맥 같은 경우에는 command + s 를 하면 저장이 되는데, 나는 누르기가 불변해 control + s 로 바꾸어두었다.

이때 control 은 윈도우 기준으로 control키 위치를 말한다.

https://insidepixce.tistory.com/91

이때 당시 영어로 정리할 때라서 영어로 되있긴 한데 console.log 함수를 다뤘던 내 게시글이다.

  • 노드 파일 실행하기

node.js 를 사용해서 방금 우리가 적은 파일을 열 수 있음

(노드 js 는 우리가 자바스크립트로 쓴 파일을 번역해주는 번역기의 종류 중 하나)

node (파일이름).js

위 내용을 콘솔에 입력해주면 된다

 

 

그리고 갑자기 나타난 에러 !!

이게 뭘까… 고민하다 몇 가지 경우의 수를 꼽아봤다.

  1. 파일 경로가 문제인 것인가?
  2. 파일이 실제로 존재하지 않나?
  3. 내가 모르는 사이에 노드 실행하기전에 무조건 저장을 해야하게ㅐ 바뀌었나?

 

결론은 1번이였다. 정말 간단한 파일에서 오류가 나서 파일 경로의 공백인건가 봤는데 실제로 파일 이름 뒤에 공백하나가 있어서 문제될 게 아니였다 , 혹은 모듈이 누락되었나? 싶어서 봤는데 모듈이 왜 필요해 콘솔로그 한 줄 찍는데…

결국 찾아낸 해결책은

cd firstweek 

javascriptlecture/firstweek/lec1.js 의 파일 경로를 가지고 있었는데

javascriptlextuire에서 lec1.js 를 실행시키라고 한다면,,, 뭐 되겠어요?

얘네가 그렇게 유동적인 친구들도 아니고… 당연히 안되는건 안되는거죠

아무튼 이러한 헤프닝이 있었습니다.

헬로월드 출력때 생긴 오류… 이건 좀… ㅋㅋ

 

  • 주석

주석은 코드 안에서 무시되는 부분이다. 보통 코드에 대해 설명할 때 많이 쓴다 .

//주석입니다

*//형태로 쓰는 사람도 많지만 나같은 경우는 command + shift + a 를 단축키로 설정하여 주석을 처리한다.*

단축키로 주석을 처리하게 되면 모양이 조금 다르다

/* 근데얘도 단축키가 있어요 단축키로 하면 더 쉬워요 */

내가 경험해본 바로는 언어마다 주석 처리가 다르고, 단축키 주석도 좀 다른 것 같았다.

이렇게 1주차 1-3 강의 끝!


review


알고 있었던 부분

→ 주석, 노드 파일 실행하기. 저장하기 , 콘솔로그

알지 못했던 부분

→ 파일 옆에 흰색 동그라미가 뜨는게 아직 저장되지 않아서 그럤다는 거 ! 처음 알았다

 

728x90
300x250
728x90
728x90

timeline


 
todo
5:00am  
6:00am  
7:00am  
8:00am  
9:00am 항해 99 접속
10:00am 공부시작
11:00am 항해 상담
12:00pm 네일아트 예약
1:00pm 네일아트
2:00pm 네일아트
3:00pm 점심식사
4:00pm 노션 정리/계획정리/인프런 강의 알아보기
5:00pm 책 찾아보기
6:00pm 저녁식사
7:00pm 웹종 1주차 듣기
8:00pm 웹종 1주차 듣기
9:00pm 웹종 1주차 듣기
10:00pm 웹종 1주차 코드스니펫 없이 썹보기/티스토리 업데이트하기
11:00pm 웹종 2주차 듣기
12:00am 웹종 2주차 듣기
1:00am 웹종 2주차 코드스니펫 없이 써보기
2:00am 웹종 2주차 코드스니펫 없이 써보기/ 24h
3:00am 티스토리 업데이트하기
4:00am  
5:00am  
 
 
 
 

 
checklist
 

 
 
 
 
 
 

 
팬명록 만들기 (with node js, react)

 
1. 백앤드 코드 쓰기 
 
 

[node.js] 사진 업로드 기능을 포함한 게시판: 백엔드 서버 구조 짜기

고민하고 고민해 만들어낸 코드의 구조는 이러하다. 순서를 바꿔보는 건 추후 첨부해보겠다 1. 모듈 불러오기 const express = require('express'); const app = express(); const { MongoClient } = require('mongodb'); const m

insidepixce.tistory.com

 

스파르타 시절 만들었던 팬명록을 노드와 리엑트로 다시 작성해볼 생각이다. 기본적인 문법은 알 것 같은데 이건 좀 ;; 하는 부분이 있었음. 

그래서 전부다 정리해보았다. 내 구글링의 흔적 !!

 


 

동기/ 비동기 정리하기 


https://insidepixce.tistory.com/102?category=1030785 

 

[node.js] 동기/비동기 한판 정리

동기/비동기 정리 동기/비동기는 자바스크립트에서 중요한 개념 중 하나이다. 동기는 코드가 순차적으로 실행된다는 것을 의미하며, 비동기는 코드가 순차적으로 실행되지 않는다는 것을 의미

insidepixce.tistory.com

 

아직까지 개념이 헷갈려서 동기/ 비동기를 한번에 정리해보았다. 

예시랑 함께 보니깐 더 쉬웠다. 

이때까지 공부한 내용 중 중요한 내용만 뽑아봤다.

 


multer 모듈


https://insidepixce.tistory.com/103?category=1030785 

 

[Node.js] Multer 모듈

Multer 모듈 Multer는 Node.js 환경에서 파일 업로드를 처리하기 위한 미들웨어이다. Express와 함께 사용하면 파일 업로드를 쉽게 처리할 수 있으며, connect-multiparty와 비교하여 더 유연하고 안정적으로

insidepixce.tistory.com

가만있자 보니 뮬터도 정리할 필요성을 느꼈다.

 

파일 업로드 시에 사용하는데, 더 좋은 방법이 이따면 추후 포스팅해 보도록 하겠다

 

 

 

오늘도 제리를 위해서 화이팅

728x90
300x250
728x90
728x90

고민하고 고민해 만들어낸 코드의 구조는 이러하다.

순서를 바꿔보는 건 추후 첨부해보겠다

1. 모듈 불러오기

const express = require('express');
const app = express();
const { MongoClient } = require('mongodb');
const multer = require('multer');
const path = require('path');

먼저 사용할 모듈은 이렇게 정했다.

const { MongoClient } = require('mongodb'); 는 MongoDB 클라이언트를 초기화하는 코드이다

multer 모듈은 파일 업로드를 처리하는 데 사용된다.

path 모듈은 파일 경로와 관련된 유틸리티 함수를 제공한가

즉, 위 코드는 express, MongoDB, multer, path 모듈을 초기화하고 해당 모듈들을 사용할 수 있도록 준비하는 역할을 한다.

요즘 공부하고 있는 모듈인 express 에 관하여 좀 적어보자면…

express 모듈 불러오기

const app = express();

이는 express 에플리케이션을 생성하는 코드

http 요청과 응답을 처리하고 라우팅, 미들웨어, 템플릿 엔진 등을 제공한다.

express() 는 express 애플리케이션 객체를 반환하는 함수이다. 이를 app 변수에 할당하여 애플리케이션 객체를 참조할 수 있도록 한다.

app 객체를 활용하여 서버의 동작을 정의하고 미들웨어를 추가하며, 라우팅을 설정할 수 있다

즉, const app = express(); 코드는 express 애플리케이션을 초기화하고 해당 애플리케이션의 객체에 대한 참조를 app 변수에 저장하는 역할을 한다.

이후 app 객체를 통해 서버의 동작을 설정하고 요청에 대한 응답을 처리할 수 있다

express란?

express는 Node.js로 작성된 웹 프레임워크이며, const app = express(); 코드는 express 애플리케이션을 초기화하고 해당 애플리케이션의 객체에 대한 참조를 app 변수에 저장하는 역할을 한다. 이후 app 객체를 통해 서버의 동작을 설정하고 요청에 대한 응답을 처리할 수 있다.

아래는 express를 사용한 간단한 예시 코드이다.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

위 코드에서 app.get은 라우팅을 설정하는 메서드로, '/' 경로로 GET 요청이 왔을 때 'Hello, World!' 문자열을 응답으로 보내주는 코드이다. app.listen은 서버를 실행시키는 메서드로, 3000번 포트로 서버를 시작한다.

2. 몽고디비 연결과 변수 설정하기

const client = new MongoClient('mongodb+srv://sparta:패스워드칸@sparta.rqx1qlk.mongodb.net/?retryWrites=true&w=majority');
let db; 

위 코드를 해석해보겠다.

해당 코드는 MongoDB 서버와 연결하는 역할을 한다.

MongoClient는 MongoDB 클라이언트를 초기화하는 코드이며, 이 코드에서는 MongoDB Atlas를 사용하고 있다.

new MongoClient()를 호출하여 몽고DB에 연결하여 client 변수에 저장한다.

패스워드칸에는 사용자의 실제 패스워드를 입력해야 한다.내 db를 연결할때는 내 비밀번호를 사용하였다

이 패스워드를 사용하여 sparta 데이터베이스에 연결한 후에는 db 변수를 선언하여, 나중에 데이터베이스에서 데이터를 조회 및 조작할 때 사용할 수 있도록 한다.

 

db변수

db 변수는 몽고디비 연결 후에 클라이언트의 db() 메서드를 사용하여 데이터베이스에 접근하는데 사용된다.

에를 들어

db.collection(collectionname')

형식으로 접근하고 쿼리를 실행할 수 있다.

데이터베이스 연겷이 성공하면 databaseConnect() 함수가 호출되고, client.cd('dbsparta) 코드를 통해 ‘dbspartq’이름의 데이터베이스에 연결된 db 변수에 데이터베이스 클라이언트가 연결된다,

이를 사용하여 데이터베이스 조작을 수행할 수있다.

즉, db 변수는 MongoDB 데이터베이스 클라이언트에 액세스하고 조작하는데 사용되는 중요한 변수이다

3. 몽고디비 데이터베이스에 연결하고 연결 상태 확인

async function databaseConnect() {
  try {
    await client.connect();
    db = client.db('dbsparta');
    console.log('MongoDB에 연결되었습니다.');
  } catch (error) {
    console.error('MongoDB 연결 오류:', error);
  }
}

위 코드의 내용을 설명해보자면,

  1. databaseConnect() 함수는 비동기 함수로 선언되어 있다.
  2. 함수 내부에서는 await client.connect(); 코드를 사용하여 client 객체가 MongoDB에 연결될 때까지 대기한다.
  3. 연결이 성공하면 client.db('dbsparta') 코드를 사용하여 'dbsparta'라는 이름의 데이터베이스에 대한 클라이언트 객체를 얻으며, 이 클라이언트 객체는 db 변수에 할당된다.
  4. 연결이 성공하면 **'MongoDB에 연결되었습니다.'*라는 메시지가 콘솔에 출력된다.
  5. 연결 중에 오류가 발생하면 catch 블록이 실행되고, 오류 메시지가 **'MongoDB 연결 오류:'*와 함께 콘솔에 출력된다.

await client.connect()

await client.connect()는 MongoDB 클라이언트가 MongoDB 서버에 연결하는 비동기 함수이다. 이 함수는 await 키워드를 사용하여 연결이 완료될 때까지 기다리고, 성공하면 클라이언트 객체를 반환한다. 이 객체는 이후 데이터베이스와의 상호 작용을 위해 사용된다.

아래는 await client.connect()를 사용하는 간단한 예시 코드이다.

async function connectToServer() {
  try {
    const client = await MongoClient.connect(url, { useNewUrlParser: true });
    console.log("서버에 연결되었다.");
    const db = client.db(dbName);
  } catch (err) {
    console.log(err.stack);
  }
}

위 코드에서 await MongoClient.connect()는 MongoDB 클라이언트가 MongoDB 서버에 연결하는 비동기 함수이다. url은 MongoDB 서버의 URL 주소를 나타내고, dbName은 연결하려는 데이터베이스의 이름이다. 연결이 성공하면 클라이언트 객체가 반환되며, 이 객체를 사용하여 데이터베이스와 상호 작용할 수 있다.

동기 비동기를 모르겟다면…

https://insidepixce.tistory.com/102

4. 파일 업로드 처리하기

const upload = multer({
  dest: 'uploads/',
  limits: { fileSize: 10 * 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
    const ext = path.extname(file.originalname).toLowerCase();
    if (allowedExtensions.includes(ext)) {
      cb(null, true);
    } else {
      cb(new Error('파일 업로드에 실패했습니다.'));
    }
  },
  onError: (err, next) => {
    next(err);
  }
});

위 코드는 파일 업로드 처리를 위한 코드이다.

먼저 만들어둔 데이터베이스 연결 코드를 입력해준다.

위 코드는 파일 업로드를 위한 multer 모듈 설정이다.

  • dest 옵션: 업로드된 파일이 저장될 경로를 지정할 수 있다.
  • limits 옵션: 업로드되는 파일의 최대 크기를 제한할 수 있디.
  • fileFilter 옵션: 업로드되는 파일의 확장자를 제한하는 필터링 함수를 구현할 수 있어. 이 함수를 사용하면 원하지 않는 파일 업로드를 방지할 수 있디.
  • onError 옵션: 업로드 중 에러가 발생할 때 처리하는 함수를 구현할 수 있어. 이 함수를 사용하면 업로드 과정에서 발생할 수 있는 문제를 미리 예방할 수 있디.

위의 옵션들은 multer 모듈을 사용하여 파일 업로드를 구현할 때 매우 유용해. 이러한 설정을 사용하면 더 안정적이고 안전한 방식으로 파일을 업로드할 수 있디.

https://insidepixce.tistory.com/102

multer에 관해서 더 보고 싶다면 이 게시글 참고

5. express 애플리케이션 미들웨어 설정/ 루트 경로에 대한 get 요청

express에 대해서는 앞에서도 짧게 설명했지만, 이 부분에 대해서는 조금 깊게 다루고 싶어 추후 포스팅할 에정이다. 이러한 개념으로 작성했다… 정도 까지만 이해해주면 고마울듯.

app.set('views', path.join(__dirname, 'templates'));
app.set('view engine', 'html');
app.engine('html', require('ejs').renderFile);

app.use(express.static('uploads'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.get('/', (req, res) => {
  res.render('index.html');
});

Express 애플리케이션의 설정을 다루며, 템플릿 파일이 위치한 디렉토리를 설정하고, HTML 템플릿 엔진을 지정하며, EJS 렌더링 엔진을 등록하고, 정적 파일을 만들고 JSON 및 URL 인코딩된 요청 본문을 파싱하고

루트 경로에 대한 GET 요청을 처리하여 'index.html' 파일을 렌더링하는 부분이다.

각각의 역할을 자세히 읽어보면 이해가 쉽다,

  1. app.set('views', path.join(__dirname, 'templates'));
    • Express 애플리케이션에서 템플릿 파일이 위치한 디렉토리를 설정
    • **__dirname**은 현재 스크립트가 실행 중인 디렉토리의 경로를 나타냄
    • **'templates'**는 템플릿 파일이 위치한 디렉토리 이름
  2. app.set('view engine', 'html');
    • Express 애플리케이션에서 사용할 템플릿 엔진을 설정
    • **'html'**은 HTML 파일을 템플릿으로 사용한다는 것을 의미
  3. app.engine('html', require('ejs').renderFile);
    • ejs 패키지를 사용하여 HTML 파일을 렌더링하는 엔진을 등록
    • renderFile 함수는 ejs 모듈에서 제공하는 함수로, HTML 파일을 렌더링하여 결과를 생성
  4. app.use(express.static('uploads'));
    • Express 애플리케이션에서 정적 파일을 제공하기 위한 미들웨어를 설정
    • **'uploads'**는 정적 파일이 위치한 디렉토리 이름
  5. app.use(express.json());
    • JSON 형식의 요청 본문을 파싱하기 위한 미들웨어를 설정
  6. app.use(express.urlencoded({ extended: true }));
    • URL 인코딩된 요청 본문을 파싱하기 위한 미들웨어를 설정
    • **extended: true**는 중첩된 객체를 파싱할 수 있도록 설정
  7. app.get('/', (req, res) => { ... });
    • 루트 경로('/')에 대한 GET 요청을 처리하는 핸들러를 설정
    • 요청이 들어오면 **'index.html'**을 렌더링하여 응답

6. 몽고디비에 업로드하기

app.post를 사용하여 몽고디비에 사용자가 작성한 내용을 업로드시켰다

app.post('/guestbook_post', upload.single('photo'), (req, res) => {
  const name = req.body.name_give;
  const comment = req.body.comment_give;
  const file = req.file;

  if (file) {
    const filename = file.filename;
    const doc = {
      name: name,
      comment: comment,
      photo: filename
    };
    db.collection('fan').insertOne(doc)
      .then(() => {
        res.json({ msg: '응원 완료!' });
      })
      .catch(() => {
        res.status(400).json({ msg: '파일 업로드에 실패했습니다.' });
      });
  } else {
    res.status(400).json({ msg: '파일이 선택되지 않았습니다.' });
  }
});

위의 코드는 Express 애플리케이션에서 /guestbook_post 경로에 대한 POST 요청을 처리하는 핸들러다.

  1. upload.single('photo') 미들웨어를 사용하여 photo 필드로 전송된 단일 파일을 업로드한다. 업로드된 파일은 req.file 객체로 접근할 수 있다.
  2. 요청 본문에서 **name_give**와 comment_give 필드 값을 추출하여 **name**과 comment 변수에 할
  3. 업로드된 파일(req.file)이 존재하는 경우, 파일 이름을 filename 변수에 할당
  4. name, comment, filename 값을 이용하여 doc 객체를 생성합니다. 이 객체는 MongoDB에 저장될 데이터를 나타냄
  5. **db.collection('fan').insertOne(doc)**를 사용하여 doc 객체를 'fan' 컬렉션에 삽입
  6. 삽입이 성공한 경우, 클라이언트에게 JSON 응답으로 **{ msg: '응원 완료!' }**를 전송
  7. 삽입이 실패한 경우, 클라이언트에게 상태 코드 400과 JSON 응답으로 **{ msg: '파일 업로드에 실패했습니다.' }**를 전송
  8. 만약 업로드된 파일이 없는 경우, 클라이언트에게 상태 코드 400과 JSON 응답으로 **{ msg: '파일이 선택되지 않았습니다.' }**를 전송

위의 코드는 /guestbook_post 경로로 POST 요청이 들어오면 파일 업로드를 처리하고 MongoDB에 데이터를 저장하는 역할을 한다. 이를 통해 게시판에 게시물을 작성하고 파일을 첨부할 수 있게 한다

7. 몽고디비로부터 이미 작성된 게시글 가지고 오기

app.get('/guestbook', (req, res) => {
  db.collection('fan').find({}, { projection: { _id: 0 } }).toArray()
    .then(allComments => {
      allComments.forEach(comment => {
        if (comment.photo) {
          comment.photo = req.protocol + '://' + req.get('host') + '/uploads/' + comment.photo;
        }
      });
      res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
      res.setHeader('Pragma', 'no-cache');
      res.setHeader('Expires', '0');
      res.json({ result: allComments });
    })
    .catch(error => {
      console.error(error);
      res.status(500).json({ msg: '서버 오류' });
    });
});
  1. **db.collection('fan').find({}, { projection: { _id: 0 } })**를 사용하여 'fan' 컬렉션의 모든 문서를 조회함. **{ projection: { _id: 0 } }**는 결과에서 _id 필드를 제외하고 조회하도록 지정한 것
  2. toArray() 메서드를 사용하여 조회된 결과를 배열로 변환
  3. Promise 체인을 이용하여 조회된 결과인 **allComments**를 처리합니다. then 블록에서는 각 댓글의 photo 필드가 존재하는 경우, 해당 경로를 조합하여 절대 URL로 변경함. 이는 클라이언트에서 댓글의 이미지를 로드할 수 있도록 함
  4. 응답에 Cache-Control 헤더를 설정하여 캐시를 사용하지 않도록 지정함
  5. **res.json({ result: allComments })**를 사용하여 JSON 형태로 **{ result: allComments }**를 응답 이는 클라이언트에게 조회된 댓글 목록을 전달
  6. 조회나 처리 중에 오류가 발생한 경우, catch 블록에서 오류를 콘솔에 기록하고 클라이언트에게 상태 코드 500과 JSON 응답으로 **{ msg: '서버 오류' }**를 전송

위의 코드는 /guestbook 경로로 GET 요청이 들어오면 MongoDB에서 'fan' 컬렉션의 댓글을 조회하여 클라이언트에게 응답하는 역할을 한다. 이를 통해 게시판의 댓글 목록을 클라이언트로 전달한다.

8. 서버 열기 (로컬호스트)

app.listen(8099, '0.0.0.0', () => {
  console.log('서버가 시작되었습니다.');
});

app.listen으로 서버를 열어주고, 서버가 정상적으로 열렸다면 ‘서버가 시작되었다’라고 알려준다.

app.listen

app.listen은 Express.js에서 서버를 시작할 때 사용하는 함수이다다. 이 함수는 서버가 특정 포트에서 요청을 수신할 수 있도록 한다

다음은 app.listen을 사용하여 서버를 시작하는 예시 코드이다

const express = require('express');
const app = express();

const PORT = 3000;

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

위의 코드에서, app.listen 함수는 PORT 변수에 저장된 포트 번호에서 요청을 수신할 준비가 되었다는 메시지를 출력하고 서버를 시작한다.

 

const express = require('express');
const app = express();
const { MongoClient } = require('mongodb');
const multer = require('multer');
const path = require('path');

const client = new MongoClient('mongodb+srv://sparta:비밀번호@sparta.rqx1qlk.mongodb.net/?retryWrites=true&w=majority');
let db; // MongoDB 데이터베이스 클라이언트를 저장할 변수

async function databaseConnect() {
  try {
    await client.connect();
    db = client.db('dbsparta');
    console.log('MongoDB에 연결되었습니다.');
  } catch (error) {
    console.error('MongoDB 연결 오류:', error);
  }
}

databaseConnect(); // 데이터베이스 연결 함수 호출

const upload = multer({
  dest: 'uploads/',
  limits: { fileSize: 10 * 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
    const ext = path.extname(file.originalname).toLowerCase();
    if (allowedExtensions.includes(ext)) {
      cb(null, true);
    } else {
      cb(new Error('파일 업로드에 실패했습니다.'));
    }
  },
  onError: (err, next) => {
    next(err);
  }
});


app.set('views', path.join(__dirname, 'templates'));
app.set('view engine', 'html');
app.engine('html', require('ejs').renderFile);

app.use(express.static('uploads'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.get('/', (req, res) => {
  res.render('index.html');
});

app.post('/guestbook_post', upload.single('photo'), (req, res) => {
  const name = req.body.name_give;
  const comment = req.body.comment_give;
  const file = req.file;

  if (file) {
    const filename = file.filename;
    const doc = {
      name: name,
      comment: comment,
      photo: filename
    };
    db.collection('fan').insertOne(doc)
      .then(() => {
        res.json({ msg: '응원 완료!' });
      })
      .catch(() => {
        res.status(400).json({ msg: '파일 업로드에 실패했습니다.' });
      });
  } else {
    res.status(400).json({ msg: '파일이 선택되지 않았습니다.' });
  }
});

app.get('/guestbook', (req, res) => {
  db.collection('fan').find({}, { projection: { _id: 0 } }).toArray()
    .then(allComments => {
      allComments.forEach(comment => {
        if (comment.photo) {
          comment.photo = req.protocol + '://' + req.get('host') + '/uploads/' + comment.photo;
        }
      });
      res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
      res.setHeader('Pragma', 'no-cache');
      res.setHeader('Expires', '0');
      res.json({ result: allComments });
    })
    .catch(error => {
      console.error(error);
      res.status(500).json({ msg: '서버 오류' });
    });
});

app.listen(8099, '0.0.0.0', () => {
  console.log('서버가 시작되었습니다.');
});

 

백앤드 코드는 끝났다. 오류가 생기면 다시 다듬어야겠지만, 클라이언트를 리엑트로 만들어 볼 예정인데, 문제가 생긴다면 다시 수정해야 할 것이다. 

728x90
300x250
728x90
728x90

 

Multer 모듈

Multer는 Node.js 환경에서 파일 업로드를 처리하기 위한 미들웨어이다. Express와 함께 사용하면 파일 업로드를 쉽게 처리할 수 있으며, connect-multiparty와 비교하여 더 유연하고 안정적으로 파일 업로드를 처리할 수 있다.

Multer는 다양한 옵션을 제공하여 파일 업로드를 보다 세밀하게 제어할 수 있으며, 다양한 예외 상황에 대한 처리도 가능하다.

예를 들어, 파일 사이즈 제한, 파일 형식 제한, 파일 이름 중복 방지 등 다양한 옵션을 설정할 수 있다. 또한, Multer는 여러 파일을 동시에 업로드할 수 있으며, 업로드된 파일의 정보를 쉽게 가져올 수 있는 API도 제공한다.

Multer 모듈은 다음과 같이 설치할 수 있다.

npm install multer

Multer를 사용하기 위해서는 먼저 multer 모듈을 임포트해야 한다.

const multer = require('multer');

 

  1. multer 모듈을 임포트한다.
  2. multer 객체를 생성한다. 이때, storage, limits, fileFilter 등의 옵션을 설정할 수 있다.
  3. multer 객체를 사용하여 파일 업로드를 처리한다. 이때, single, array, fields 등의 메소드를 사용하여 파일 업로드를 처리할 수 있다.

파일 업로드 처리

multer는 http 요청의 본문에 포함된 파일을 서버로 업로드할 수 있도록 지원함

upload.single(fieldname) 또는 upload.array(fieldname[, maxCount])과 같은 메서드를 사용하여 단일 파일 또는 여러 파일을 처리할 수 있음

const multer = require('multer');
const upload = multer({ dest: 'uploads/' });

app.post('/profile', upload.single('ramona'), (req, res, next) => {
  // req.file은 `ramona` 파일에 대한 정보
  // 키(`avatar`)는 multer 미들웨어가 사용되는 필드
})

  • multer는 HTTP 요청의 본문에 포함된 파일을 서버로 업로드할 수 있도록 지원한다
  • upload.single(fieldname) 또는 upload.array(fieldname[, maxCount])과 같은 메서드를 사용하여 단일 파일 또는 여러 파일을 처리할 수 있다
  • upload.single(fieldname)은 fieldname 필드의 단일 파일을 처리한다
  • req.file 객체는 파일에 대한 정보를 담고 있다. fieldname은 upload.single() 메서드가 사용되는 필드 이름

파일 저장 경로 및 이름 지정

업로드된 파일의 저장 경로와 이름을 지정할 수 있다.

const multer = require('multer');
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now())
  }
});
const upload = multer({ storage: storage });

  • storage 옵션을 설정해 파일 저장 위치, 파일 이름 규칙, 파일 확장자 등을 제어할 수 있다.
  • multer.diskStorage() 메서드를 사용하여 파일 저장 경로와 파일 이름 규칙을 설정한다.
  • cb 콜백 함수를 사용하여 저장 경로와 파일 이름을 반환한다.
  • cb(null, 'uploads/')는 업로드된 파일이 uploads 폴더에 저장되도록 지정한다.
  • cb(null, file.fieldname + '-' + Date.now())는 파일 이름을 fieldname-현재시간 형식으로 지정

파일 유효성 검사

filefilter 옵션을 설정하여 허용되는 파일 확장자, 파일 크기 등을 제한할 수 있다.

const multer = require('multer');
const upload = multer({
  storage: storage,
  fileFilter: function (req, file, cb) {
    // 파일 필터링 로직
    if (!file.originalname.match(/\\\\\\\\.(jpg|jpeg|png|gif)$/)) {
      return cb(new Error('Only image files are allowed!'));
    }
    cb(null, true);
  }
});

  • fileFilter 옵션을 설정해 허용되는 파일 확장자, 파일 크기 등을 제한할 수 있다.
  • fileFilter 콜백 함수는 업로드할 파일의 유효성을 검사한다.
  • 파일이 유효한 경우 cb(null, true)를 호출한다.
  • 유효하지 않은 경우 cb(new Error('Only image files are allowed!'))와 같이 에러를 반환한다

여러 필드 처리

단일 파일 뿐만 아니라 여러 필드(텍스트, 파일)등을 동시에 처리할 수 있다

const multer = require('multer');
const upload = multer();

app.post('/profile', upload.fields([
  { name: 'avatar', maxCount: 1 },
  { name: 'gallery', maxCount: 8 }
]), (req, res, next) => {
  // req.files는 `avatar`와 `gallery` 파일에 대한 정보
  // 키(`avatar`와 `gallery`)는 multer 미들웨어가 사용되는 필드명
})
  • 단일 파일 뿐만 아니라 여러 필드(텍스트, 파일)등을 동시에 처리할 수 있다.
  • upload.fields(fields) 메서드를 사용하여 여러 필드를 처리한다.
  • fields는 배열 형태로 필드 정보를 담고 있다
  • 필드 정보는 { name: 필드이름, maxCount: 파일 수 }의 형태로 지정한다.
  • req.files 객체에는 { 필드이름: 파일정보 } 형태로 정보가 담겨 있다.
728x90
300x250
728x90
728x90

썸네일 돌려쓰기

동기/비동기 정리

동기/비동기는 자바스크립트에서 중요한 개념 중 하나이다. 동기는 코드가 순차적으로 실행된다는 것을 의미하며, 비동기는 코드가 순차적으로 실행되지 않는다는 것을 의미한다. 비동기 코드는 예측할 수 없는 순서로 실행되며, 실행이 완료되면 콜백 함수가 호출된다.

동기 코드의 예시는 다음과 같다.

function add(x, y) {
  return x + y;
}

const result = add(1, 2);
console.log(result); // 3

위 코드에서 add 함수는 두 개의 숫자를 더한 값을 반환하는 일반적인 함수이다. 함수가 호출되면 결과가 즉시 반환되며, 결과는 result 변수에 할당된다. 이것은 동기 코드이다.

비동기 코드의 예시는 다음과 같다.

setTimeout(() => {
  console.log('Hello, World!');
}, 1000);

위 코드에서 setTimeout 함수는 일정 시간이 지난 후에 실행될 콜백 함수를 등록하는 함수이다. 이 함수는 1초 후에 'Hello, World!' 문자열을 콘솔에 출력한다. 이것은 비동기 코드이다. setTimeout 함수가 호출되면 결과가 즉시 반환되지 않으며, 1초 후에 콜백 함수가 호출된다.

따라서 자바스크립트에서는 비동기 함수를 항상 콜백 함수와 함께 사용해야 한다. 이를 통해 비동기 코드의 실행 순서를 보장하고, 비동기 함수가 완료된 후에 콜백 함수를 호출할 수 있다.

예시

동기와 비동기를 이해하기 위해 일상 생활에서의 예시를 들어볼 수 있다.

예를 들어, 음식을 주문하는 것을 생각해보자. 동기 방식에서는 주문을 하면 음식이 나올 때까지 대기하며, 결과가 반환될 때까지 다른 일을 할 수 없다. 반면, 비동기 방식에서는 주문을 하고 나면 다른 스케줄을 세우거나, 다른 주문을 하거나, 롤이나 한 판 하는 등 다른 작업을 할 수 있다. 음식이 나오면 알림을 받아서 음식을 수령하고 먹으면 된다.

 

이와 같이 동기 방식은 결과가 반환될 때까지 대기해야 하며, 다른 작업을 수행할 수 없다. 반면, 비동기 방식은 결과가 반환되기를 기다리지 않고 다른 작업을 수행할 수 있다.

  • [ 시나리오 1 ]
  • 개발팀장이 3명의 사원에게 동시다발적으로 각각의 업무를 지시한다. ( = 비동기 )
  • 놀랍게도 개발팀장은 3명의 사원에게 시킨 일을 확인도 안하고 본인 할 일도 한다 ( = 비동기 )
  • 사원마다 맡은 일을 알아서 끝내고 개발팀장에게 보고한다. ( = 논블로킹 )
  • [ 시나리오 2 ]
  • 개발팀장이 사원1 에게 업무를 지시한다.
  • 그리고 사원1 업무가 끝날때까지 언제 끝나냐고 눈초리를 준다. ( = 동기 )
  • 사원1 의 업무처리가 너무 느려서 다른 사원에게 일을 주려고한다. ( = 비동기 )
  • 그런데 사원1 은 도와달라며 개발팀장의 옷자락을 붙잡는다. ( = 블로킹 )
  • 그걸 지켜보는 사원2 와 사원3 은 무슨 일을 주던 열심히 할 생각은 있지만 일이 없다. ( = 동기 )

요약

동기/비동기 프로그래밍은 모든 프로그래밍 언어에서 중요한 개념 중 하나이다. 동기 프로그래밍은 코드가 순차적으로 실행되며, 결과가 즉시 반환된다는 것을 의미한다. 비동기 프로그래밍은 코드가 순차적으로 실행되지 않으며, 결과가 바로 반환되지 않는다는 것을 의미한다.

비동기 함수는 대개 비동기 콜백 함수와 함께 사용되며, 콜백 함수는 비동기 함수가 완료된 후에 호출된다. 이를 통해 프로그램이 예측 가능한 방식으로 실행되는 것을 보장할 수 있다. 예를 들어, 파일을 읽는 비동기 함수는 파일이 성공적으로 읽혔을 때 콜백 함수를 호출하여 결과를 반환한다.

동기 함수와 비동기 함수는 각각의 장단점이 있으며, 상황에 따라 적절한 방식을 선택해야 한다. 일반적으로, 네트워크 요청과 같은 오래 걸리는 작업을 수행할 때는 비동기 함수를 사용하는 것이 좋다. 이를 통해 사용자 인터페이스가 응답성을 유지하면서 백그라운드 작업이 수행될 수 있다.

 

728x90
300x250

+ Recent posts