[JSTS-009][중급] 파일을 읽어 로컬 서버로 전달하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[JSTS-009][중급] 파일을 읽어 로컬 서버로 전달하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 126회 작성일 26-09-04 00:36

본문

[이번 수업]

Node.js가 운영체제와 만나는 세 통로를 연결합니다. 파일을 읽고, 실행 인자와 환경값을 받은 뒤, 로컬 HTTP 서버의 응답을 확인합니다. 외부 패키지와 외부 서버는 쓰지 않습니다.

[선수지식]

ES 모듈의 import와 async·await가 필요합니다. `node --version`으로 Node.js가 실행되는지 확인하세요.

[학습목표]

1. 파일·프로세스·네트워크 API의 역할을 구분합니다.
2. 파일 읽기와 HTTP 요청을 await로 처리합니다.
3. 로컬 주소와 임시 포트로 서버를 실행하고 닫습니다.

[핵심개념]

`node:fs/promises`는 Promise를 반환하는 비동기 파일 API입니다. `readFile`에 `utf8`을 지정하면 문자열을 얻습니다. 파일 전체를 읽으므로 큰 파일에는 스트림 방식이 더 알맞습니다.

프로세스는 실행 중인 프로그램입니다. `process.argv`의 앞 두 항목 뒤부터 사용자가 전달한 인자가 들어옵니다. `process.env`는 현재 프로세스의 환경변수를 문자열로 제공합니다.

HTTP 서버는 요청을 받아 상태, 헤더, 본문으로 응답합니다. `127.0.0.1`은 자기 컴퓨터에서만 접근하는 루프백 주소입니다. 포트 0은 운영체제가 비어 있는 포트를 고르게 합니다. 예제는 내장 fetch로 한 번 요청합니다.

[따라하기]

message.txt를 만들고 `hello` 한 줄을 적습니다. 이어서 app.mjs를 만듭니다.

```javascript
import { readFile } from "node:fs/promises";
import { createServer } from "node:http";

const fileName = process.argv[2] || "message.txt";
const prefix = process.env.APP_PREFIX || "LOCAL";
const message = (await readFile(fileName, "utf8")).trim();

const server = createServer((request, response) => {
  if (request.method !== "GET" || request.url !== "/") {
    response.writeHead(404);
    response.end("not found");
    return;
  }
  response.writeHead(200, { "content-type": "text/plain; charset=utf-8" });
  response.end(`${prefix}: ${message}`);
});

await new Promise((resolve) => {
  server.listen(0, "127.0.0.1", resolve);
});

try {
  const address = server.address();
  const result = await fetch(`http://127.0.0.1:${address.port}/`);
  console.log(`status=${result.status}`);
  console.log(await result.text());
} finally {
  server.close();
}
```

Windows PowerShell에서는 다음처럼 실행합니다.

```powershell
$env:APP_PREFIX = "DEMO"
node app.mjs message.txt
$env:APP_PREFIX = $null
```

macOS와 Linux에서는 `APP_PREFIX=DEMO node app.mjs message.txt`로 실행합니다. 예상 결과는 같습니다.

```text
status=200
DEMO: hello
```

첫 줄은 HTTP 성공 상태이고 둘째 줄은 환경값과 파일 내용을 합친 응답입니다. finally가 서버를 닫아 포트를 계속 점유하지 않게 합니다.

[흔한 실수]

await를 빼면 파일 내용 대신 Promise를 다룹니다. 상대 경로는 명령을 실행한 현재 폴더가 기준이므로 다른 폴더에서 실행하면 파일을 못 찾을 수 있습니다. `server.close()`를 빠뜨리면 프로그램이 끝나지 않을 수 있습니다. 실패 경로도 반드시 시험하세요.

[보안 주의]

본인 소유의 로컬·격리 환경에서만 실행합니다. 루프백 주소를 공유 네트워크 주소로 바꾸지 마세요. 실제 서비스는 사용자가 보낸 파일 경로를 readFile에 바로 넘기지 않고 허용 폴더·이름인지 확인하며 크기도 제한합니다. 환경변수 전체, 토큰, 민감한 파일을 로그나 응답에 넣지 않습니다. 요청 메서드와 경로도 허용 목록으로 검사합니다.

[직접 해볼 과제]

GET `/health`에는 파일을 읽지 않고 `ok`를 반환하세요. fetch 주소를 `/health`로 바꿔 상태 200과 본문 ok를 확인하고, 알 수 없는 경로가 404를 내는 요청도 추가하세요.

[확인문제]

1. process.argv에서 사용자가 적은 첫 번째 인자는 몇 번째 위치에 있나요?
2. 서버가 포트 0으로 listen하면 실제 포트는 누가 선택하나요?
3. 외부 입력을 파일 경로로 곧바로 사용하면 왜 위험한가요?

[다음 학습]

다음은 WEB-009 브라우저 저장소·쿠키·세션입니다. 브라우저와 서버가 상태를 어디에 보관하는지 배웁니다.

[공식 참고 자료]

Node.js 24 LTS 파일 API
https://nodejs.org/docs/latest-v24.x/api/fs.html#promises-api

Node.js 24 LTS 프로세스 API
https://nodejs.org/docs/latest-v24.x/api/process.html#processargv

Node.js 24 LTS HTTP API
https://nodejs.org/docs/latest-v24.x/api/http.html#httpcreateserveroptions-requestlistener

Node.js 24 LTS fetch
https://nodejs.org/docs/latest-v24.x/api/globals.html#fetch

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
1,241
어제
5,103
최대
16,772
전체
772,295
Copyright © 소유하신 도메인. All rights reserved.