본문 바로가기

이것 저것 공부/프론트엔드 백엔드 몰입교육

14일차

전체적인 코드는 제 github 가시면 소스 있습니다.

import http from 'http'
//html 파일 표준 중에 하나로 {}있는 것은 export default같은 것이 없는 것
import {URL} from 'url'
import fs from 'fs'
// 파일 입출력을 위한 모듈과 웹서버를 위한 모듈
const port = 8080;

// 서버 생성 시 같은 디렉토리에 있는
// http:localhost:8080/home.html 이런 바뀌는 html 부분만 읽어서 서버에 
// 해당 파일이 있으면 보내주고 없으면 없다고 한다.
http.createServer((req, res) =>{
    console.log(req.url); //url을 넣어준다.
    console.log(req.method); // get, post를 구분
    const urlObj = new URL(
        req.url,
        "http://exam.com"

    )
    console.log(urlObj.pathname);
    let header = {
        'Content-Type' : 'text/html'
    }
    let _path = './www' + urlObj.pathname;
    console.log(_path);

    try{ // 성공했을 때 data에 .html 파일의 내용이 전달된다.
        let data = fs.readFileSync(_path);
        res.writeHeader(200, header);
        res.end(data);
    }
    catch(e){ // 실패했을 때
        header['Content-Type'] = 'text/html'
        res.writeHeader(200, header);
        res.end('file not found');
    }


}).listen(port);

console.log(`listen port :${port}`);

 

서버를 실행시키고 아래처럼 실행해보면 나온다.

curl과 웹 방식

npm node-static

정적웹서버를 위한 플러그인

npm install node-static

https://www.npmjs.com/package/node-static 

여기 들어가면 자세한 사용법을 알 수 있다.

import http from 'http'
import nodestatic from 'node-static'


const port = 8080;
const fileServer = new (nodestatic.Server)('./www');

http.createServer((req, res)=>{
    console.log(req.url);
    fileServer.serve(req, res);

}).listen(port)

console.log(`listen ${port}`);

nodestatic.server를 통해서 파일 서버 인스턴스를 만듭니다. 

이것은 현재 디렉토리의 파일을 제공합니다. 그렇기에 특정 디렉터리에 있는 파일을 제공하려면 첫 번째 인수로 전달해야 한다.

 

디렉토리 아래에서 파일 제공

디렉터리 아래에 있는 파일을 제공하려면 인스턴스 에서 serve메서드를 호출 Server하고 HTTP 요청 및 응답 개체를 전달하기만 하면 됩니다.

 

정적 웹서버 from scratch

npm init -> 엔터하고 필요한 내용만 입력

type: module 추가하기

new URL(파싱할 url 문장, "상대경로일 경우 앞에 붙일 호스트 주소")

 

정적 웹서버와의 데이터가 올바르게 오고 가고 있는지 확인하기 위해서 지금까지 curl을 사용하였다. 하지만 rest client를 사용하면 더욱 간편하게 검사할 수 있다. 그렇기에 rest client 버전을 사용해보았다.

/*
import http from 'http'
import {URL} from 'url'
const port = 8090

http.createServer((req, res) =>{

    const urlObj = new URL(
        req.url,
        'http://exam.com'
    );

    let result = {
        r: 'ok'
    };
// 제이슨 객체 자체를 보낼 수 없어서 바이너리객체이므로 그래서 스트링으로 만들어서 보냄
// 요청한 쪽에서 이걸 받아서 다시 파싱하여 사용
    res.end(JSON.stringify(result));
    let header ={
        'Content-Type' : 'text/plain',
        'Access-Control-Allow-Origin' : '*',
        'Access-Control-Allow-Methods' : 'GET',
        'Access-Control-Max-Age' : '1000',
        "Access-Control-Allow-Headers" : "*"// cors정책 허용 
    }
    let _title = urlObj.searchParams.get('title');
    let _msg = urlObj.searchParams.get('msg');

    result._title = _title;
    result._msg = _msg;
    res.writeHead(header);
    res.end(JSON.stringify(result));
}).listen(port);

console.log(`listen : ${port}`);

*/
import http from 'http'
import { url } from 'inspector';
import {URL} from 'url'

const port = 8090

http.createServer((req,res)=> {

    const urlObj = new URL(
        req.url,
        'http://example.com'
    );

    console.log(`pathname : ${urlObj.pathname}`);
    console.log(`search : ${urlObj.search}`);
    console.log(`hostname : ${urlObj.hostname}`);

    let result = {
        r: 'ok'
    }
    let header = {
        'Content-Type': 'text/json',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET',
        'Access-Control-Max-Age': '1000',
        "Access-Control-Allow-Headers": "*" //CORS 정책 허용  * 는 모두 허용 
    }
    res.writeHead(200,header);
// 파싱


    if(urlObj.pathname === '/echo'){ // 에코 요청 처리
        let _title = urlObj.searchParams.get('title');
        let _msg = urlObj.searchParams.get('msg');

        result.title = _title
        result.msg = _msg

    }
    else if(urlObj.pathname === '/sum'){
        // 다 문자열로 들어오니까 숫자로 처리하기 위함
        let a = parseInt(urlObj.searchParams.get('a'));
        let b = parseInt(urlObj.searchParams.get('b'));
        
        result.cal = a + b;

    }
// api가 많을 경우 switch case 사용
    res.end(JSON.stringify(result));

}).listen(port);

console.log(`listen : ${port}`);

먼저 에코 요청 처리하는 것과 a와 b가 주어졌을 때 합을 구하는 것을 파싱하도록 작성하였다.

그 과정에서 curl과 rest 둘 다 사용하였습니다.

url 구조

hostname/pathname?search

search->  parm=1&parm2=2&param3=3 -> 파라메터가 여러개이면 &로 구분

 

curl 방식

curl의 GET의 다중 파라메터 전송

-d : 함께 전달할 파라미터값 설정하기

-G : 전송할 사이트 url 및 ip 주소

ex1) curl -i -X GET -d "msg=hello&title=nodejs" -G http://localhost:8090/echo

ex2) curl -i -X GET -d "a=1&b=2" -G http://localhost:8090/sum

rest client 방식

rest client의 경우 화면에 보이는 것 처럼 Send Request를 누르면 Response창이 뜬다.

 

http 상태코드

res.writeHeader(상태코드,헤더정보)

200 -> 성공

400-> 실패(클라이언트측 책임)

500-> 실패(서버측 책임)

 

그렇기에 위에서 writeHeader를 사용할 때 200을 넣어서 예를 들었던 것이다.

만약 여러 실패를 나타내기 위해서 사용될 때는 다른 상태 코드를 넣어주어야 한다.

node-fetch

npm node

promise

es6 대표적인 비동기 객체

setTimeout

waterfall

resolve -> 다음 체인으로 넘기는 것

then -> 동기식으로 체인화된다.

동기화가 필요한 로직단위를 묶어서 체인으로 관리

 

async, awit

async 함수 - > 함수 내에서 동기화 키워드인 await를 사용할 수 있다. 

그 동기화 내에서는 블럭에만 걸림 전체적인 시스템에는 영향을 주지 않는다. 

promise와 같이 사용하여 비동기 코드의 가독성을 올릴 수 있다.

 

object clonning, deep copy