...
static
static 미들웨어는 express에서 제공하는 기본 미들웨어이며 express 객체 안에서 꺼내 바로 사용할 수 있다.
app.use('요청 경로', express.static('실제 경로'));
app.use('/', express.static(path.join(__dirname, 'public')));
기본 경로인 / 로 왔을 때, express는 public 폴더 안에 있는 해당 경로의 파일을 찾는다.
즉 https://localhost:3000/css/style.css 와 같은 요청을 하게 되면, 실제 static에서 반환하는 파일은 ./public/css/style.css가 된다.
public 디렉토리 아래에 있는 다음과 같은 폴더와 파일들을
Express/public/index.html
Express/public/css/style.css
Express/public/js/main.js
Express/public/css/style.css
아래와 같은 경로로 접근할 수 있게 된다.
http://localhost:3000/index.html
http://localhost:3000/css/style.css
http://localhost:3000/js/main.js
http://localhost:3000/css/style.css
이 경우 실제 서버의 폴더 경로에는 public이 들어 있더라도 요청 주소에는 public이 들어 있지 않다.
서버의 폴더 경로와 요청 경로가 다르므로 외부인이 서버의 구조를 쉽게 파악할 수 없으며, 이는 보안에 큰 도움이 된다.
하지만 public은 워낙에 유명하니, public-3030 같이 써서 서버 구조에 대한 보안에 신경을 써준다.
또한 정적 파일들을 알아서 제공해주기 때문에 일일히 fs.readFile로 파일을 직접 읽어서 전송할 필요가 없다.
만약 요청 경로에 해당하는 파일이 없으면 알아서 내부적으로 next를 호출한다.
그러나 파일을 발견했다면 다음 미들웨어는 실행되지 않는다. 응답으로 파일을 보내고 next를 호출하지 않기 때문이다.
// 만일 public폴더안에 index.png라는 사진 파일이 있고, 사용자가 localhost:3000/index.png 요청을 한다면
app.use(morgan('dev')); // get 200 ~ 요청 로그가 찍힌다.
app.use('/', express.static(path.join(__dirname, 'public'))); // static경로로서 png파일을 제공하고 끝난다. 즉, next()를 안해버린다.
app.use(express.json()); // 미들웨어 실행이 안된다.
app.use(express.urlencoded({ extended: false })); // 미들웨어 실행이 안된다.
app.use(cookieParser(process.env.COOKIE_SECRET)); // 미들웨어 실행이 안된다.
// 만일 public폴더안에 about이라는 경로가 없고, 사용자가 localhost:3000/about 요청을 한다면
app.use(morgan('dev')); // get 200 ~ 요청 로그가 찍힌다.
app.use('/', express.static(path.join(__dirname, 'public'))); // 경로에 about이 없으니 next()를 한다.
app.use(express.json()); // next()를 한다.
app.use(express.urlencoded({ extended: false })); // next()를 한다.
app.use(cookieParser(process.env.COOKIE_SECRET)); // next()를 한다.
app.get('/about', (req, res) => {
// ... 실행 된다.
}
express.static 같은 미들웨어는 정적 파일을 제공할 때 next 대신 res.sendFile 메서드로 응답을 보낸다.
따라서 정적 파일을 제공하는 경우 그 뒤의 미들웨어들은 실행되지 않는다.
미들웨어 확장법
[로그인 여부에 따른 페이지뷰 설정]
로그인 한 클라우드에게는 특정페이지를 보여주고, 아니면 안보여주는 형식을 만들어보자.
app.use(morgan('dev');
app.use(cookieParser(process.env.COOKIE_SECRET);
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
}));
// 일부러 아래 둔다.
app.use('/', (req, res, next) => {
// 미들웨어 안에다 둔다.
if (req.session.id) // 세션 아이디가 있다면 (로그인 상태라면)
express.static(path.join(__dirname, 'public'))(req, res, next); // public에서 에셋을 보여준다
else // 세션 아이디가 없다면
next(); // 다음 미들웨어 실행
}
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use 안에서 넣는 콜백함수는 블록 내에서, 익스프레스가 알아서 (req, res, next)를 붙여 호출한다.
그런데 미들웨어 안에 두는 express.static은 누가 따로 (req, res, next)를 붙이는 게 없으므로 직접 (req, res, next)를 붙여 호해야 한다.
express.static(path.join(__dirname, 'public'))(req, res, next);
참고로 (req, res, next) => { ... }는 app.use 안에 넣었으므로 익스프레스가 (req, res, next)를 붙여 호출 하는 형태이다.
Reference
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.