생활코딩

Coding Everybody

App - 파일을 이용해 본문 구현

토픽 생활코딩 > WEB > WEB2 - Node.js

수업소개

파일에 본문을 저장하고, Node.js의 파일 읽기 기능(fs.readFile)을 이용해서 본문을 생성하는 방법을 살펴봅니다. 

 

 

 

강의

?id= 의 값을 정의하지 않았을 때 제목과 본문에 undefined가 뜨는 문제는 뒤에서 해결 방법을 배우게 됩니다. 조금만 기다려주세요. 

 

 

 

소스코드

main.js

변경사항

var http = require('http');
var fs = require('fs');
var url = require('url');

var app = http.createServer(function(request,response){
    var _url = request.url;
    var queryData = url.parse(_url, true).query;
    var title = queryData.id;
    if(_url == '/'){
      title = 'Welcome';
    }
    if(_url == '/favicon.ico'){
      return response.writeHead(404);
    }
    response.writeHead(200);
    fs.readFile(`data/${queryData.id}`, 'utf8', function(err, description){
      var template = `
      <!doctype html>
      <html>
      <head>
        <title>WEB1 - ${title}</title>
        <meta charset="utf-8">
      </head>
      <body>
        <h1><a href="/">WEB</a></h1>
        <ul>
          <li><a href="/?id=HTML">HTML</a></li>
          <li><a href="/?id=CSS">CSS</a></li>
          <li><a href="/?id=JavaScript">JavaScript</a></li>
        </ul>
        <h2>${title}</h2>
        <p>${description}</p>
      </body>
      </html>
      `;
      response.end(template);
    })


});
app.listen(3000);

 

댓글

댓글 본문
  1. Sansol Park
    "../coding.js" 로 접근하려 했으나 올바른 접근 방법은 "../web2-nodejs/coding.js" 입니다. 즉, 이미지 파일에 접근하기 위해서는 이미지가 있는 폴더의 경로를 포함하여 상대 경로를 정확히 지정해주어야 합니다.
    대화보기
    • 비전공자
      오후 11:42 2024-04-20
    • 김철흥
      2024.01.10
      완료!
    • Hoon Ko
      20231016
    • 수상한용이
      23.10.05 완료
    • carpediem
      23.09.03 완료!!
    • BF_Lee
      23.06.28
      파일읽기를 통해 글의 내용을 수정해도 껏다키지 않고 자유롭게 할 수 있게됨
    • 어흥
      23.06.28.
    • 고경록
      강의에서 삭제한 "data/HTML" 파일 내 <img src="coding.jpg" width="100%"> 를 제대로 표시하려면 어떻게 해야하나요? 이미지가 data 의 상위 폴더인 web2-nodejs 에 있으니 "../coding.js" 으로 하면 될 줄 알았는데 안 되네요ㅠㅠ..
    • 코지마 히데오 뺨 후릴 반바지
      23.02.28 완료!
    • 백대진
      23.01.18
    • 감자
      22.12.01 완료
    • 드가자
      따라는 하고 있는데 왜 이렇게 되는건지 이해를 못하고 있다
    • 당당
      2022.10.16
    • 뿔고래
      쿼리를 사용하여 입력값에 따라 다른 문자열을 출력하는 노드js를 사용하면 웹페이지가 여러개인척 할 수 있다.
    • i_am_es
      2022-08-05
    • 아캔두잇
      20220804 완료
    • 키다리아저씨
      220715완
    • toonfac
      220714 오후 2시 01분 완료
    • 이성훈
      2022/06/23 완료
    • 코지마 히데오 뺨 후릴 반바지
      와안료
    • 코지마 히데오 뺨 후릴 반바지
      오 친절한 설명 감사합니다 ㅋㅋ 저도 코드 따라 쳤는데 "오헤헹. 왜 안되누?" 이러고 있다가
      잘 보니까 폴더 위치가 이상하더라구요 ㅋㅋㅋ
      대화보기
      • 난할수있어
        다들 디렉토리 조심하세요. nodejs 디렉토리에 1,2,3, index, main.js 있고 data폴더는 nodejs 바로 하위폴더여야 합니다. 디렉토리 안맞추면 본문에 undefiend만 나와요. 이거가지고 몇시간 헤맴
      • 밍기
        2022-01-14 완료
      • 소설가
        2021-1-6 완료
        고맙습니다.
      • node.js가 mvc패턴을 취하는 php로 제작하는 사이트에 비해 동적으로 생성된다는 것이 정확히 어떤 것인지 궁금합니다.
        어짜피 프론트 코드 개발자가 만들어야 하는 것은 같지 않나요?
      • 김관호
        21.11.23
      • BlitzcrankNautilusSeraphine
        맞아요 이 문제는 당일에 모든 강의를 수강하고 `과 '의 차이를 늦게나마 알아차려서 문제를 해결했습니다. 답장 감사합니다.
        대화보기
        • 일억개
          효율적인 코딩을 하려면 template literal 문법을 쓰는 것이 좋겠습니다.
          `data/${queryData.id}` 이렇게 그레이브 액센트로 감쌋나요?
          대화보기
          • BlitzcrankNautilusSeraphine
            제 경우가 특이한건지 위의 코드가 잘못된건지 아래 댓글을 보니까 더 혼란스러워지네요 ㅋㅋ
            파일경로를 파라미터로 전달할때 ${} 를 쓰면 의도대로 되지않는 일이 있었습니다.
            실제로 코드를 따라가면서 뭐가 문제인지 확인하고 해결하였습니다.


            <문제발생>
            fs.readFile('data/'+queryData.id, 'utf8', function(err, description){
            var template = `
            <!doctype html>
            <html>
            <head>
            <title>WEB1 - ${title}</title>
            <meta charset="utf-8">
            </head>
            <body>
            .. 생략
            </body>
            </html>
            `;
            response.end(template);
            })
            ..

            위의 readFile 함수에서 첫번째 파라미터로 READ할 FILE의 위치를 전달하는데
            단순히 'data/${queryData.id}' 로 전달 시 readFile이 파일의 경로를 queryData.id를 집어넣어서

            data/HTML
            data/CSS
            data/JavaScript 로 인식하는게 아닌
            data/${queryData.id} 라는 파일을 찾아서 출력하는 현상이 발생했습니다.

            그렇기 때문에 아무리 id를 다르게 전달해도 data 디렉터리 내 ${queryData.id}라는 파일만을 가져가게되고.
            실제로 같은 이름의 파일을 만들어서 시험해본 결과 가설이 맞았습니다.


            <문제해결>

            readFile('data/' + queryData.id, ...생략.. ) 으로 전달하여 경로자체를 + 연산으로 만들었습니다.

            다들 파이팅하십셔
          • 일억개
            0:40 1.html 파일에서 <p> 잘못 잘렸네요
          • 일억개
            3:55 웹서버 만들기 수업에 나오는 코드(이 수업의 초기 코드) 또한 사진을 없애고 새로고침 하니까, 바로 반영이 되더군요..
          • 자스마스터
            211001
            왜케어렵지 ㅜㅜ 원리를 모르겠다 일단 패스....
          • pdpd
            9일이나 지나서 이제는 해결하셨을거 같습니다만.... 33번 라인에
            <p><${description}</p>

            인데 <P> 다음에 < 가 하나 더껴져 있어서 그런것 같습니다.
            애당초에 html코드도 안되는게 정상일텐데..... 역시 스크립트 언어는 대충 돌아는 가는게 대단하지 않나 싶습니다...
            대화보기
            • Ribosom
              감사합니다.
            • R.A.E
              안녕하세요? HTML파일을 잘 읽어들이는데, 나머지 두개의 파일을 읽어내지 못하는 경우는 왜 그런 걸까요?
              디렉토리 문제도 아니고, txt로 저장되지도 않았고, 파일명도 queryData.id, title과 동일한데 정말 이유를 알 수가 없네요...ㅠㅠㅠㅠ

              저의 코딩은 이렇습니다.

              var http = require('http');
              var fs = require('fs');
              var url = require('url');

              var app = http.createServer(function(request,response){
              var _url = request.url;
              var queryData = url.parse(_url, true).query;
              var title = queryData.id;
              if(_url == '/'){
              title = 'Welcome';
              }
              if(_url == '/favicon.ico'){
              return response.writeHead(404);
              }
              response.writeHead(200);
              fs.readFile(`data/${queryData.id}`, 'utf8', function(err, description){
              var template = `
              <!doctype html>
              <html>
              <head>
              <title>WEB1 - ${title}</title>
              <meta charset="utf-8">
              </head>
              <body>
              <h1><a href="/">WEB</a></h1>
              <ul>
              <li><a href="/?id=HTML">HTML</a></li>
              <li><a href="/?id=CSS">CSS</a></li>
              <li><a href="/?id=JavaScript">JavaScript</a></li>
              </ul>
              <h2>${title}</h2>
              <p><${description}</p>
              </body>
              </html>
              `;
              response.end(template);
              })


              });
              app.listen(3000);
            • 전해성
              21.09.11 완료
            • 초딩 개발자
              2021/09/11
            • 졸작완성하자
              21.09.07 완료. 인턴 때 회사에서 배웠을때는 백엔드 너무 어렵다고 생각해서 프론트엔드쪽으로 갔는데, 생활코딩에서 배우니까 너무 쉽고 좋은 것 같아요ㅎㅎ 감사합니다 :)
            • Young-Ki Kim
              허. 저는 본문이 잘 바뀌기는 하는데 Terminal 명령창에 계속 undefined가 나오네요.
            • 개발자말랑이
              마지막에 효과음이 생겼네요 ㅎㅎ
            • 고영히
              0823 완료
            • Kangmin Kim
              2021.8.22 완료!
            • 승뇽뇽
              노드 넘넘 강려크하다
            • 삼각자
              한참 헤맸는데 제가 파일명에 소문자만 써서 undefined 떴다는 걸 알았을 때 허무함... 강의 잘 봤습니다 ㅠㅠ
            • 박사장
              21 07 28 완료!
            • Mark Kim
              맥 os 사용자 분들 중, 소스 코드를 그대로 사용하여도 본문이 로드 되지 않을 시에, readFile메소드의 file path 를 터미널에서 표시되는 파일의 absolute file path 를 사용하시거나 소스파일 디렉토리를 기준으로 한 relative file path 를 사용하시면 본문을 성공적으로 불러 올 수 있습니다.
            • labis98
              20210720 completed!
            • Duke
              2021.07.17
            • 한민서
              이미지가 올려지지 않는 이유를 살펴보니... url 대신 data/${queryData.id}를 읽어오기 때문에 이미지를 요청할 때 이미지를 읽어오지 못하는 것이었습니다.

              url.parse()가 deprecated돼서 new URL().searchParams을 쓰신 분들은 그 코드 때문에 그럴 겁니다.

              제가 해결한 방법은 바로 ?id=HTML처럼 id를 사용하여 문서를 요청할 땐 문서를 보내주고 사진을 요청할 땐 사진을 보내주는 것입니다.
              data/HTML 문서에서 이미지 태그를 <img src="/picture/coding.jpg" width="100%"> 이렇게 수정해서 picture 디렉터리로 요청하도록 하고, main.js에서는 이미지를 보내주기 위해서

              if(_url.indexOf("/picture/") == 0) // '/picture'로 시작하는 url을 요청했을 경우 이미지를 가져온다
              {
              var imgSrc = _url.substr(1); // 이미지 파일 이름 가져오기
              fs.readFile(imgSrc, function(err, data){ // 이미지 파일을 읽어온다
              response.writeHead(200, {'Content-Type': 'image/jpeg'})
              response.end(data) // Send the file data to the browser.
              })
              return;
              }

              위 코드를 11번 라인 다음에 넣으면 됩니다. 그리고 이미지는 data와 마찬가지로 picture 폴더 안에 넣으면 됩니다. 코드는 mano님이 올려주신 글이랑 https://not-to-be-reset.tistory.com/263 이 글을 참고했어요.
              대화보기