Node.js

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

수업소개

파일에 본문을 저장하고, 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. 김관호
    21.11.23
  2. 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
        왜케어렵지 ㅜㅜ 원리를 모르겠다 일단 패스....
      • 9일이나 지나서 이제는 해결하셨을거 같습니다만.... 33번 라인에
        <p><${description}</p>

        인데 <P> 다음에 < 가 하나 더껴져 있어서 그런것 같습니다.
        애당초에 html코드도 안되는게 정상일텐데..... 역시 스크립트 언어는 대충 돌아는 가는게 대단하지 않나 싶습니다...
        대화보기
        • Ribosom
          감사합니다.
        • 안녕하세요? 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!
        • 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 이 글을 참고했어요.
          대화보기
          • warmpeace
            완료이긴 하지만 계속 반복해야 완전히 체득될 것 같아요~! 감사합니다!
          • Jeong Il Haan
            20210413
          • 서쥐서쥐
            210402 완료
          • koabc0999
            response.end(template); 가 readfile 익명함수 내부에 들어가야하는 이유를 잘 모르겠어요.
            template를 미리 익명함수 외부에서 선언해두고 익명함수 내부에서 데이터를 할당해주면
            template의 내부 데이터는 사라지지않고 남아있어야 할 것 같은데 다시 이전의 데이터로 돌아가는것 같은 결과가 나와요. 왜 이럴까요? ㅋㅋㅋ
          • qufstar7
            3번째 방법으로 main.js파일 상위폴더로 옳기니까 됬습니다.
            코드 비교하고 검색하고 이것저건 고생했는데 감사합니다~
            대화보기
            • 이수완
              아톰 러너로 키니까 undefined 뜨다가 cmd로 키니까 되네요 ㅠ_ㅠ ..
            • byoonn
              완료
            • 밀키
              2021.02.22 완료
            • chimhyangmoo
              21.02.18
            • jeisyoon
              2021.02.06 App - 파일을 이용해 본문 구현 완료
            • 나그네
              잘 되었네요.~^^;
              .
              .
              처음에 안되서 헤매다가....
              cd web2-nodejs 디렉토리가 틀려서 안되었습니다.
            • 마아앙
              2021.01.31
            • 마아앙
              일단 유튜브 동영상이 어떻게 로드가 되었는지 참고해보세요! 그러다보면 CSS서버, JS파일 서버를 각각 만들어서 이것에게 포트번호(ex. http://localhost:1563/)를 부여하고 Main서버에있는 a테그의 href에다가 http://localhost:1563/를 넣어주면 이미지를 불러올겁니다!
              대화보기
              • 임찬혁
                완료
              • 뭄수
                완료
              • ohhigo
                21/1/22 ★★★★★
                동적페이지 본문 구성
              • HTML클릭 시 이미지도 같이 올리고 싶어서 도전했으나 실패했다.

                https://stackoverflow.com......age
                에서 첫번째 답변에서 fs.readFile('image.jpg', function(err, data) {를 fs.readFile('coding.jpg', function(err, data) {
                으로 변경한 후 http://localhost......에 접속하여 이미지가 뜨는 것 까지 확인!

                나중에 실력이 생기면 다시 해보자
              • wnstjd9701
                2021-01-18
              • 할수이다
                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);


                저는 이렇게 해서 성공했는데요...
                이게 참.... cmd가 반응이 느린건지 계속 undi 가 뜨다가 아무것도 안뜨다가 해서 CSS,HTML,JavaScript 파일 안에 아무글자 떄려넣고 다시 cmd ctrl+c 로 나왔다가 node main.js로 들어가서 페이지 f5 갈기니까 갑자기 글자들이 와라라라라 나타났어요! 제가 다시 한번 한국인임을 느낍니다....천천히 해보셔요 다들
              • well-being
                undefined 에러가 뜨는 경우 정리
                1. fs.readFile(`data/${queryData.id}` ~~ 에서, ` <-- 기호가 따옴표(')가 아니라 탭위에있는 `기호일 때

                2. .txt파일로 저장되었을 경우, ${queryData.id}.txt를 붙이지 않았을 때

                3. data라는 폴더 상위에 main.js 파일이 위치하지 않았을 때.
              • 2020.12.31 완료!
              • 이상운
                20/12/29완료
              • 손민철
                20/12/29 완료
              • 풀스택개발자
                2020 12 28
              • 생활둘기
                2020 12 24
              • kkn1125
                20.12.21 완료~!
              버전 관리
              egoing
              현재 버전
              선택 버전
              graphittie 자세히 보기