Javascript/node.js

node.js - http, express (210224)

꿀먹는매미 2021. 2. 24. 09:40

nodejs

   http client

      = 브라우저 기능

      = 크롤링(스크래핑)

   1. ajax / 로그인 (o)

         phantomjs + setTimeout

            getElementById

   2. ajax / 로그인 (x)

      urllib / axios

 

   *dom 처리

        string

        cheerio

 

   http server

   = tomcat + servlet

      1. http.createServer().listen(포트번호)

      2.

         let parseUrl = new URL( req.url );

          parseUrl.pathname = ??

      3. post / get

      => framework

 

 


새로 작업할 폴더를 생성

mkdir httpex2

cd httpex2

npm init -y

 

mkdir public_html

touch public_html/gugudan.html

touch public_html/gugudan_ok.html

touch public_html/error.html

 

code

open folder

 

gugudan 소스

 

기본 네비게이터

브라우저에 url로 접속해서 각 페이지로 이동하는 기본구조

// server1.js
"use strict";

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

// server
const server = http.createServer( (req, res ) => {
      // controller
      let parseUrl = url.parse( req.url, true );

      if( parseUrl.pathname == '/gugudan' ) {
            fs.createReadStream( './public_html/gugudan.html' ).pipe( res );
      } else if( parseUrl.pathname == '/gugudan_ok' ) {
            fs.createReadStream( './public_html/gugudan_ok.html' ).pipe( res );
      } else {
            fs.createReadStream( './public_html/error.html' ).pipe( res );
      }

}).listen( 8080, () => {
      console.log( '8080 포트에서 요청 대기중 ...' );
});

 

 

각 페이지의 html파일

<!-- gugudan.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>gugudan.html</h1>
            <form action="./gugudan_ok" method="get">
                  dan : <input type="text" name="dan" />
                  <input type="submit" value="전송" />
            </form>
      </body>
</html>
<!-- gugudan_ok.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>gugudan_ok.html</h1>
            <hr /><br />
            ${ result }
      </body>
</html>
<!-- error.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>error.html</h1>
      </body>
</html>

 

 

gugudan => get방식

// server1.js
"use strict";

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

// server
const server = http.createServer( (req, res ) => {
      // controller
      let parseUrl = url.parse( req.url, true );

      if( parseUrl.pathname == '/gugudan' ) {
            fs.createReadStream( './public_html/gugudan.html' ).pipe( res );
      } else if( parseUrl.pathname == '/gugudan_ok' ) {
            if( req.method.toLocaleLowerCase() == 'get' ) {
                  let query = parseUrl.query;

                  //let result = query.dan;
                  let result = '<table width="800" border="1">';
                  result += '<tr>';
                  for( let i=1; i<=9; i++ ) {
                        result += '<td> ' + query.dan + ' X ' + i + ' = ' + ( parseInt(query.dan) * i ) + '</td>';
                  }
                  result += '</tr>';
                  result += '</table>';

                  const html = fs.readFileSync( './public_html/gugudan_ok.html' );
                  const tplHtml = eval( '`' + html.toString().replace( /`/g, '\\`' ) + '`' );
                  res.end( tplHtml );
            }
      } else {
            fs.createReadStream( './public_html/error.html' ).pipe( res );
      }

}).listen( 8080, () => {
      console.log( '8080 포트에서 요청 대기중 ...' );
});

실행결과

get방식에서는 ?dan=6이 url에 추가됨

 

gugudan => post 방식

// server2.js
"use strict";

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

const querystring = require( 'querystring' );

// server
const server = http.createServer( (req, res ) => {
      // controller
      let parseUrl = url.parse( req.url, true );

      if( parseUrl.pathname == '/gugudan' ) {
            fs.createReadStream( './public_html/gugudan.html' ).pipe( res );
      } else if( parseUrl.pathname == '/gugudan_ok' ) {
            if( req.method.toLocaleLowerCase() == 'post' ) {
                  
                  let buffer = '';

                  req.on( 'data', chuck => {
                        buffer += chuck;
                  });

                  req.on( 'end', () => {
                        const query = querystring.parse( buffer );

                        //let result = query.dan;
                        let result = '<table width="800" border="1">';
                        result += '<tr>';
                        for( let i=1; i<=9; i++ ) {
                              result += '<td> ' + query.dan + ' X ' + i + ' = ' + ( parseInt(query.dan) * i ) + '</td>';
                        }
                        result += '</tr>';
                        result += '</table>';

                        const html = fs.readFileSync( './public_html/gugudan_ok.html' );
                        const tplHtml = eval( '`' + html.toString().replace( /`/g, '\\`' ) + '`' );
                        res.end( tplHtml );
                  });

            }
      } else {
            fs.createReadStream( './public_html/error.html' ).pipe( res );
      }

}).listen( 8080, () => {
      console.log( '8080 포트에서 요청 대기중 ...' );
});

실행결과

get방식과 결과는 같지만 url에 추가로 query가 붙지 않음

 


우편번호 검색

zipsearch       public_html/zipsearch.html

zipsearch_ok   public_html/zipsearch_ok.html

기타              public_html/error.html

 

기본설정

mkdir zipsearchex1

cd zipsearchex1/

npm init -y

npm install mariadb          // mariadb와 연동해서 사용하므로 꼭 추가

 

mkdir public_html

touch public_html/error.html

touch public_html/zipsearch_ok.html

touch public_html/zipsearch.html

 

zipsearch => post 방식

 

html 파일들 소스

<!-- zipsearch.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>zipsearch.html</h1>
            <form action="./zipsearch_ok" method="post" >
                  동이름 : <input type="text" name="dong" />
                  <input type="submit" value="전송" />
            </form>
      </body>
</html>
<!-- zipsearch_ok.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>zipsearch_ok.html</h1>
            ${ result }
      </body>
</html>
<!-- error.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>error.html</h1>
      </body>
</html>

 

 

우편번호 검색기

// server.js
"use strict";

const http = require( 'http' );
const fs = require( 'fs' );
const url = require( 'url' );
const querystring = require( 'querystring' );

const mariadb = require( 'mariadb/callback' );

const server = http.createServer( (req, res ) => {
      let parseUrl = url.parse( req.url, true );

      if( parseUrl.pathname == '/zipsearch' ) {
            fs.createReadStream( './public_html/zipsearch.html' ).pipe( res );
      } else if( parseUrl.pathname == '/zipsearch_ok' ) {
            if( req.method.toLocaleLowerCase() == 'post' ) {
                  
                  let buffer = '';

                  req.on( 'data', chuck => {
                        buffer += chuck;
                  });

                  req.on( 'end', () => {
                        const query = querystring.parse( buffer );

                        //let result = query.dong;

                        const conn = mariadb.createConnection( {
                              host: 'localhost',
                              user: 'root',
                              password: '!123456',
                              database: 'project'
                        });

                        const sql = 'select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like ?';

                        conn.query( sql, query.dong + '%', ( err, rows ) => {
                              if( !err ) {
                                    let result = '<table width="800" border="1"';
                                    rows.forEach( row=> {
                                          result += '<tr>';
                                          //console.log( row.zipcode, row.sido, row.gugun, row.dong, row.ri, row.bunji );
                                          result += '<td>[' + row.zipcode + ' ' + row.sido + ' ' + row.gugun + ' ' + row.dong + ' ' 
                                          + row.ri + ' ' + row.bunji + '</td>';
                                          result += '</tr>';
                                    });
                                    result += '</table>';
                                    
                                    const html = fs.readFileSync( './public_html/zipsearch_ok.html' );
                                    const tplHtml = eval( '`' + html.toString().replace( /`/g, '\\`' ) + '`' );
                                    res.end( tplHtml );
                              }
                              conn.end();
                        });                   
                  });
            }
      } else {
            fs.createReadStream( './public_html/error.html' ).pipe( res );
      }

}).listen( 8080, () => {
      console.log( '8080 포트에서 요청 대기중 ...' );
});

실행결과

 

 



HTTP 프레임워크

  1. express
    https://expressjs.com
  2. koa
  3. hapi
 

Express - Node.js web application framework

Fast, unopinionated, minimalist web framework for Node.js $ npm install express --save

expressjs.com

express에 대해 안내서와 api 참조


express

 

cd

mkdir express1

cd express1/

npm init -y

npm install express

 

먼저 port 3000 개방

su - root

cd /usr/lib/firewalld/services/

firewall-cmd --reload

 

middleware 사용 - 안내서( 미들웨어 작성 )

// express1.js
"use strict";

const express = require( 'express' );

const app = express();
//console.log( app );

// middleware

app.listen( 3000, () => {
      console.log( '3000번 포트에서 요청 대기 중 ...' );
});

const myMiddleware = (req, rep, next) => {
      console.log( 'MiddelWare' );
      next();
}

app.use( myMiddleware );

app.get( '/', (req, rep) => {
      rep.send( 'Hello Express' );
});

 

 

route 사용( 안내서 - 라우팅 )

// express2.js
"use strict";

const express = require( 'express' );

const app = express();

app.listen( 3000, () => {
      console.log( '3000번 포트에서 요청 대기 중 ...' );
});

// Routing
// get
app.get( '/', (req, rep) => { rep.send( '/ get 요청' ); });
app.get( '/users', (req, rep) => { rep.send( '/users 요청' ); });
app.get( '/items', (req, rep) => { rep.send( '/items 요청' ); });

// post
app.post( '/', (req, rep) => { rep.send( '/ post 요청' ); });

 

 

route 경로

// express3.js
"use strict";

const express = require( 'express' );

const app = express();

app.listen( 3000, () => {
      console.log( '3000번 포트에서 요청 대기 중 ...' );
});

// Routing
app.get( '/ab?cd', function(req, rep) { rep.send( '/ab?cd' ); });
app.get( '/ab+cd', function(req, rep) { rep.send( '/ab+cd' ); });
app.get( '/ab*cd', function(req, rep) { rep.send( '/ab*cd' ); });
app.get( '/ab(cd)?e', function(req, rep) { rep.send( '/ab(cd)?e' ); });

url 경로에서

/ab?cd 는 /acd or /abcd 와 일치

/ab+cd 는 /abcd, /abbcd  /abbbcd 등과 일치

/ab*cd 는 /abcd, /abxcd, /abRABDOMcd  /ab123cd 등과 일치

/ab(cd)?e 는 /abe  /abcde와 일치

 

route 핸들러

// express4.js
"use strict";

const express = require( 'express' );

const app = express();

app.listen( 3000, () => {
      console.log( '3000번 포트에서 요청 대기 중 ...' );
});

app.get( '/', (req, res, next) => {
      // Middleware 역할
      console.log( 'Hello Middleware' );
      next();
}, (req, res) => {
      res.send( 'Hello Express' );
});

 

middleware 역할을 해서

터미널에 출력한뒤 next()로 넘어가서

send 수행

 

에러 표시 / 에러 처리 / redirect

// express5.js
"use strict";

const express = require( 'express' );

const app = express();

app.listen( 3000, () => {
      console.log( '3000번 포트에서 요청 대기 중 ...' );
});

app.get( '/', (req, res) => {
      //res.status( 403 ).end();
      //res.status( 404 ).send( 'Bad Request' );

      //res.redirect( 'https://www.daum.net' );
      const html = `<!DOCTYPE html>
      <html>
            <head>
                  <meta charset="utf-8" />
            </head>
            <boad>
                  <h1>index.html</h1>
            </boad>
      </html>`;

      res.set( 'Content-Type', 'text/html' );
      res.send( html );
});

app.get( '/html', (req, res) => {
      console.log( __dirname );

      res.sendFile( __dirname + '/index.html' );
});

 

에러표시
에러 처리
redirect

index.html은 빈파일이지만 html 소스를 보내서 출력함

/html로 접속하면 디렉토리 주소가 터미널에 출력됨

 

 

express로 요청 주고 받기

public_html폴더를 만들고 form.html과 form_ok.html을 생성

<!-- form.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>form.html</h1>
            <form action="/form_ok" method="get">
                  data : <input type="text" name="data" />
                  <input type="submit" value="전송" />
            </form>
            <br /><hr /><br />
            <form action="/form_ok" method="post">
                  data : <input type="text" name="data" />
                  <input type="submit" value="전송" />
            </form>
      </body>
</html>
<!-- form_ok.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>form_ok.html</h1>
      </body>
</html>
// server.js
"use strict";

const express = require( 'express' );

const app = express();

app.listen( 3000, () => {
      console.log( '3000번 포트에서 요청 대기 중 ...' );
});

app.get( '/', (req, res) => {
      //console.log( req.headers );
      console.log( req.headers[ 'user-agent' ] );
      console.log( req.ip )

      res.sendFile( __dirname + '/index.html' );
});

app.get( '/form', (req, res) => {
      res.sendFile( __dirname + '/public_html/form.html' );
});

app.get( '/form_ok', (req, res) => {
      //console.log( 'get', req.query );              // json 데이터 표시
      console.log( 'get', req.query.data );
      res.sendFile( __dirname + '/public_html/form_ok.html' );
});

app.use( express.urlencoded( { extended: true } ) );        // post 방식 전송

app.post( '/form_ok', (req, res) => {
      //console.log( 'post', req.body );
      console.log( 'post', req.body.data );
      res.sendFile( __dirname + '/public_html/form_ok.html' );
});
/*
app.all( '/form_ok', (req, res) => {
      console.log( 'all' );
      res.sendFile( __dirname + '/public_html/form_ok.html' );
});
*/

루트 페이지로 접속하면 index.html 페이지가 출력되고

터미널에 브라우저 정보와 ip주소가 출력됨

/form으로 접속

위 - get방식 / 아래 - post 방식
get방식 전송
post방식
터미널 출력

 

 

 


 

express로 구구단 만들기

 

public_html 폴더에 gugudan.html, gugudan_ok.html 생성

<!-- gugudan.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>gugudan.html</h1>
            <form action="./gugudan_ok" method="get">
                  dan : <input type="text" name="dan" />
                  <input type="submit" value="전송" />
            </form>
      </body>
</html>
<!-- gugudan_ok.html -->
<!DOCTYPE html>
<html>
      <head>
            <meta charset="utf-8" />
      </head>
      <body>
            <h1>gugudan_ok.html</h1>
            <hr /><br />
            ${ result }
      </body>
</html>

 

 

 

 

express로 우편번호 검색기 만들기