안녕하세요 깍돌이입니다.

오늘은 Express.js의 에러 핸들러 처리에 대해서 작성하려고 합니다.

사실 기존에는 관련 내용 작성이 안되어있었는데 사실 검색하면 워낙 많이들 나오는 내용이라 작성하지 않았습니다.

기본적인것들로 블로그 포스팅을 다 채우고 싶지 않았습니다. ( 조회수는 많이 늘어날텐데 ㅎㅎ;;)

초창기에 기본적인거 쓴건 히스토리용으로 냅두고 있습니다.

 

그외에는 작업하면서 경험한것들 잊어 버리지 않기 위해서 작성하고 있습니다.

 

그럼 금일은 뭐때문에 작성하게 되었냐면 Express.js의 ERROR 처리를 위한 Middleware처리는 2개의 방법이 있습니다.

 

ERROR Middleware 500 

기본적인 500 에러입니다. express.js의 서버에서 오류가 났을 경우 흔히들 볼수있는 Internal Server Error 오류입니다.

그래서 express.js에서는 해당 에러를 처리하기 위해서

Express Router Controller안에 있는 next라는 함수를 통해서 해당 next에 error객체를 넣어서 넘기고있습니다. 

Express의 error객체를 next에 넘겨 버리게 되면 기본적인 Middleware패턴에서 해당 에러 객체를 가진 함수로 넘어가게 됩니다.

 

 

app.ts 의 구현부는 아래와 같습니다.

 

 

ERROR Middleware 404 

기본적으로 Express는 middleware 패턴이라는 것을 알고 있다는 것을 감안하고 작성하겠습니다.

 

위의 Express Router 안에서 예외처리를 하는 catch 문에서 next(error) 를 사용을 했다는 것은 기본적으로 Express에서 선언된 Router가 매치가 됐다는 뜻입니다.

 

예를들어

http://localhost:5555/testRouter

http://localhost:5555/testNotExist

로 요청시에

 

Express에 router.get('/testRouter') 만 있다면 아래의 testNotExist는 매치가 되지 않습니다. 

그렇기 때문에 결국 Express에서 선언되는 Middleware중 매치되는 것을 찾지 못하고 가장 마지막 Middleware로 가게되는데요

 

 

그래서 가장 마지막 생성된 함수의 Middleware 함수로 넘어가게되고 해당 함수에서는 매치된 값을 찾지 못하였다는 에러 메시지를 res객체를 통해 반환하는 함수가 됩니다.

그래서 404 와 그 외 내부 예외처리를 통한 500 에러 크게 2가지로 나눌 수 있습니다.

 

이슈상황

그래서 이슈상황이 뭐냐! 네 위에 설명과 다르게 동작하는 경우 입니다.

 

네 맞습니다. next에 error 객체를 넣어서 넘겼을 경우 Middleware (500) 에러 함수(ERROR 객체가 선언된 함수 ) 로 넘어가져야 합니다. 

그런데 위의 상황에서는 404 ( 라우트가 매치 되지않았을 경우 ) 로 넘어가게 됩니다.

 

물론 둘다 오류의 상황은 맞기 때문에 상관없지 않나? 라고 생각 할수 있습니다.

 

하지만 개발하였을때 예상하지 못한 동작의 흐름에 생겼을 경우는 코드를 작성한 사람의 문제일 확률이 매우 높고 앞으로도 제대로 알지 못하는 케이스가 발생가능하기 때문에 해당 원인을 찾아보고자 했습니다.

 

 

Express.js 홈페이지

500 에러 함수 설명

라우트 맨 마지막에 선언 하여야 하며 -> OK

err 에 대한 인수가 있어야합니다. -> OK 

 

 

"next() 함수로 어떠한 내용을 전달하는 경우('route'라는 문자열 제외), Express는 현재의 요청에 오류가 있는 것으로 간주하며, 오류 처리와 관련되지 않은 나머지 라우팅 및 미들웨어 함수를 건너뜁니다. 이러한 오류를 어떻게든 처리하기 원하는 경우, 다음 섹션에 설명된 것과 같이 오류 처리 라우트를 작성해야 합니다."

 

-> 조금 잘못알고 있었네요 next 함수로 어떠한 내용 전달시 요청 오류로 간주하고 나머지 라우팅 건너 뜀 ( 여튼 OK )

 

제가 사용하고있는 형태는 기본 오류 핸들러 ( 404가 아닌 모든 오류를 받아서 처리함 ) 로 보이는데 특이사항은 없어 보입니다.

 

그럼 원인은 하나일거같습니다. next로 error를 넣지 않는건가?

 

에러가 발생한 로직입니다.

HTTP 요청 중 URL 오류가 발생해서 해당 axios.get  부분에서 catch 로 빠진 부분인데요  실제로 에러 객체를 reject하였고

 

하나씩 모든 에러를 따라가다보니

 

중간에 reject를 error가 아닌 error.message 

ERROR객체가 아닌 string으로 한 부분이 있었습니다... ㅜ

황급히 수정시  

 

역시 코드를 거짓말을 하지 않습니다...

 

사실 잠깐 그냥 봤을때는 원인이 잘 안보였는데 포스팅 을 하면서 한땀한땀 찾아가다보니 복병을 발견했네요.. 

 

다시 이런일 없기를 바라면서 히스토리로 남겨놓겠습니다.

 

감사합니다.

 

 

 

 

안녕하세요 깍돌이 입니다. 오늘은  간단한 트러블 슈팅 입니다.

폐쇠망 서버에 Node.js Agent를 심어야 하는 경우가 있는데 해당 서버에 새롭게 설치를 하려고하면

Node.js 설치 파일 및 Agent 코드를 심어 놓습니다. ( node_modules 포함 ) 

 

기존에 서버들은 노드 버전이 13 14 버전을 사용했는데 이번에 새로 하는 노드로 설치시 내부 의존성으로 설치하여 실행하던 PM2 명령어들이 먹지 않는 현상이 발생했습니다.

 

결론은 맨밑에 있습니다.

Node.js 버전

[root@private-inter-comm-send transaction-test]# node -v
v16.14.0
[root@private-inter-comm-send transaction-test]# npm -v
8.3.1
[root@private-inter-comm-send transaction-test]#

package.json

"scripts": {
    "dev": "nodemon app.js",
    "start": "pm2 start app.js --name 'ServerNode'",
    "nacl": "pm2 start app.js --name 'ServerNode' -- nacl",
    "udp": "pm2 start app.js --name 'ServerNode' -- udp",
    "list": "pm2 list",

 

기존에 사용하던 명령어는 npm run start 

 

[root@private-inter-comm-send transaction-test]# npm run start

> servernode@0.0.1 start
> pm2 start app.js --name 'ServerNode'

sh: pm2: command not found
[root@private-inter-comm-send transaction-test]#

 

sh: pm2: command not found

분명히 깔려는 있는데 연결이 안되는거 같습니다.

내부 폴더의 ./node_modules/pm2로 정상실행되는 모습입니다.

 

 

정상적으로 실행되는 경우

 

node랑 npm 버전이 다른거는 큰차이가 없을거 같아서 심링크를 확인해보겠습니다.

 

연결 문제는 아닌거같네요

 

package-lock.json 확인시

 

 

비정상 package-lock.json 을 보니 node_modules가 붙어있는데 

 

npm audit fix 

npm audit 으로 꼬여져있는 부분들을 재 설치 후 다시 말아서 이동

별효과 없음

 

이외에 별짓 다해봤는데

 

노드 16버전에 문제가 있다고 생각되어서 노드 14.19 마지막 버전으로 내리고 정상화되었습니다.

 

내부적으로 노드 14버전을 LTS로 가지고 작업해야겠네요

 

다시 정상화 되었네요;

 

 

14.19 버전으로 당분간 사용하는것으로 하겠습니다.

 

 

 



Node.js 웹 어플리케이션 프레임워크 - > Express !  뭔가 이름부터 짱짱 멋지네요


비슷한 프레임워크로 koa가 있다고는 하는데 뭔가 익숙한 Express에 대해서 작성 해놓으려고 합니다.


현재 사용중인 버전은 express 4.16.3 버전을 사용중에 있습니다. (2018-09-19)


이외에 같이 사용중인 npm Module은


cors 2.8.4

iconv-lite 0.4.24

morgan 1.9.1

multer 1.3.1

joi 13.6.0

faker 4.1.0 정도가 있겠네요


Node.js 가 설치 된 상태라고 가정 시에


express를 설치 하겠습니다.



      mkdir praticeExpress
      cd praticeExpress
      // npm 초기화 
      npm init 
      // express 설치 
      npm i express 
      // express 구조 파악을 위한 express-generator 설치  전역에서 사용하기 위한 -g 옵션 
      npm i express-generator -g 
      // 단순 구조파악을 위한 pug 프로젝트 생성
      express --view=pug testApp
      cd testApp
      npm install
      // LInux 기준 실행 
      npm start
  


구조 파악을 위한 generator 후에 구조 입니다.


.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug

[공식 홈페이지 https://expressjs.com/ko/starter/generator.html ]



app.js 부터 보겠습니다.


1. app.js

불러 오는 모듈들이 엄청 많네요

http-errors,express,path,cookie-parser,morgan, ./routes/index , ./routes/users


이중에서 불러오는 모듈들에 대해서는 각각 모듈에 대해 검색? 으로 찾을수 있는 부분들이라고 생각되서 이를 제외한 것들에 대한 확인을 하였습니다.


var app = express; // 공식 홈페이지에 이와같이 쓸수 있도록 가이드 되었습니다. 따라갑시다


// views -> 사용하는 템플릿 엔진 이 있는 디렉토리 설정 

app.set('views ', path.join(__dirname,'views'));

// 뷰 엔진 설정 - express에서 사용할 템플릿 엔진을 설정합니다. pug로 생성했기 때문에 pug로 지정하네요

app.set('view engine','pug');


// * 만약에 뷰엔진을 지정하지 않았을시에는 index.pug 라고작성해 주어야 하지만

// * 뷰 엔진을 pug로 지정하였을 경우는 index라고만 써도 index.pug로 인식하여 동작합니다.

// * res.render('index')      < - > res.render('index.pug')


// ** 템플릿 엔진 사용시에는 관련 모듈도 설치 하셔야됩니다. npm i pug 



// app.use

공식 홈페이지에는 이와같이 나타나있습니다.


지정되는 경로에서 지정된 미들웨어 기능을 탑재


app.use([Path],callback[,callback ...])


path : 미들웨어 기능이 호출되는 경로  Default [ '/' ]

 - 경로를 나타내는 문자열

 - 경로와 패턴

 - 경로와 일치하는 정규식 패턴

 - 위의 조합의 배열


callback : 콜백 함수                         Default : None

 - 미들웨어 기능

 - 일련의 미들웨어 기능 , 로 구분 

 - 미들웨어 기능의 배열

 - 위의 조합의 배열

자세한 내용은 따로 포스팅 하겠습니다.  

아래의 코드들에 대해 설명을 달자면

// express.json 은 express 16 버전 부터 사용 가능 

// express 내장 미들웨어 로 JSON 을 구문 분석 및 Content-type 헤더가 type 옵션과 일치 하는 요청을 보고하는

// 미들웨어를 반환하여 use ( 현재 express에서 사용 합니다. )

// 만약에 Content-type이 맞지 않거나 등의 오류가 발생하면 request 는 req.body 에 채워지는데 {} 값으로 채워집니다.


app.use(express.json());


// urlencoded 역시 내장된 미들웨어로 body의 인코딩을 UTF-8 로 받아 처리해준다.

// extended: 옵션은 기본값은 true이며 true일 경우  

// URL-encoded data와 querystring library 또는 qs 라이브러리 사이의 파싱을 선택할수 있게 허용한다.

// false로 주게 되면 이 부분은 허용하지 않게 한다. ( express 자체적으로 처리 )

app.use(express.urlencoded({ extended: false }));


// express 내장 미들웨어로 루트 디렉토리에서 정적 데이터들 위치를 지정한다. 

// req.url 로 제공된 root디렉토리 와 결합하여 제공할 파일을 결정 

app.use(express.static(path.join(__dirname,'public')));


// 라우터를 사용  -> routes 에서 다시 

app.use('/',indexRouter);

app.use('/users',usersRouter);


// 이외 코드들은 express 에러 핸들링 코드로 되어있는데 이부분은 따로 다뤄야 할것 같습니다.!


2. bin

실행 파일을 놓은 폴더 입니다.  (현재는 어떤 느낌인지 정도만 보고 넘어갑니다.)

3. package.json

현재 사용하는 npm 프로젝트의 의존성 파일입니다.

4. public

정적 파일로 사용할 폴더입니다. 대부분 리소스 파일들을 놓습니다.

해당 폴더를 사용하기 위해서 app.js에서는

express.static이라는 메서들를 사용합니다.

app.use(express.static(path.join(__dirname,'public')));


5. routes

express에서 use로 사용하기로 되어있던 라우터들이 있는 폴더 입니다.

app.use('/',indexRouter);

app.use('/users',usersRouter);

// 로사용 


var express = require('express');


// **** express.Router는 새로운 Router 오브젝트를 반환 해주는 express API 입니다.

var router = express.Router();



/* GET users listing. */

// / 로 작성하였지만 실제 app.js에서는 app.use('/users'/로 경로를 지정하기 때문에

// / 로 작성하여도 실제 동작은 /users 가 됩니다. 


// get으로 /totalUser 라고 작성시에는 실제로는

// /users/totalUser에 대한 라우팅을 실행합니다. ** app.use('/users', ... ) 로 호출하였을 시에


router.get('/',function(req,res,next) {

res.send('respond with a resource');

});


// 위의 만들어진 router를  module.exports를 통하여 exports 합니다. 


// app.js 에서는 var userRouter = require('./routes/users'); 로 사용 

module.exports = router; 


6. views

express에서 사용할 뷰 (views) 템플릿 엔진이 있는 폴더 입니다.

app.set('views ', path.join(__dirname,'views')); 로 지정 



generator를 통해서 기본적인 구조를 파악 한 후에 간단한 더미데이터를 던져 주는 서버를 제작해 보았습니다.


// dummy Data Server

https://github.com/lgance/VanillaJS/tree/master/myVanillaJS/legacy/dummyServer


사용은 


git clone https://github.com/lgance/reactStudy.git 로 클론을 뜬 후에 내부에 dummyServer가 있을 겁니다.


cd dummyServer 


npm update ( package.json 과 package-lock.json 을 통한 모듈 설치 -> git에는 node_modules를 올리지 않음 )


node app.js


요청은  localhost:3505/dummys?columns=20&rows=50 와같이 사용하시면 됩니다.


원하는 컬럼과 로우에 맞게 데이터를 던져 줍니다(JSON) 


[결과]













안녕하세요 노드에서 파일 작업을 하여야 하는 경우가 생겼는데 예전에 한번 썻었지만 기억도 나지않고


예전에 사용했던 경우는 그냥 단순 파일 쓰는 작업만 해서 이번에는 폴더가 있는지 체크해서 없으면


해당 폴더를 만든후에 -> 폴더를 만들고 해당 폴더 안에 파일을 작성하는 것을 포스팅 하려고합니다.


노드버전은 LTS버전인 10.6 기준입니다.


우선 기본적으로 알아야 할 것이 있습니다.


__dirname;


개인변수명 작성시에 preFix로 __로 지양 해야 겠네요 

File System 에 대한 내용은 전부 docs 에 너무 잘되어있기 때문에 다른점은 참고 하셔도 될것 같습니다.


/* Node.js docs 10.6.0 Documentation - File System */

https://nodejs.org/dist/latest-v10.x/docs/api/fs.html



const fs = require('fs');

const _path = __dirname;

console.log(_path);


결과는 현재 폴더 트리의 위치가 나타나게 됩니다. __dirname을 알고 있어야 어느 폴더로 이동하여서


노드가 실행 되어도 문제가 되지 않을것 같습니다.




const fs = require('fs');

const currPath = __dirname+"/_test_/";
let version =currPath+'Fixed/';


let arr = ['linearlayout','button','datepicker'];

let contents_ =['content','tea','test','b','e','t','set','s','hg'];

let writeFile = (filename,contents)=> {
            
    fs.open(filename,'w',(err,fd)=>{
            if(err) throw err;
            console.log('file Open - :',filename.split('/')[filename.split('/').length-1]);
           fs.writeFile(fd,contents.join(','),(err)=>{
                        if(err) throw err;
                    console.log(filename + ' - write\n');
                });
    });
};
try{

       if(!fs.existsSync(version)){
                console.log(version.split('/')[version.split('/').length-1]+" 폴더가 없습니다.생성합니다.");
              fs.mkdir(version,0700,function(err){
                        if(err) throw err;
                    for(let i=0;i<3;i++){
                            writeFile(version+arr[i]+'.txt',contents_);
                    }
            });
        }
       else{
                console.log(version.split('/')[version.split('/').length-2]+" 폴더가 존재합니다.");
                    for(let i=0;i<3;i++){
                            writeFile(version+arr[i]+'.txt',contents_);
                    }
        }

}
catch(err){console.error(err);}

finally{
        console.log('File System Working Clean');
}
       






공간 데이터 (Spatial Data) : 지구상에 있는 집, 도로 등을 점이나 선 등의 형태로 나타낸 위치 데이터를 말함


1차원 데이터를 위해 만든 B-Tree 인덱싱 방법으로 2차원 데이터를 저장하면 속도가 떨어지기 때문에 


위도,경도와 같은 공간 데이터 , 즉 2차원 데이터의 좌표 값을 데이터베이스에 저장할 때는 공간 인덱싱 방법 사용


공간 인덱싱은 데이터 베이스에서 2차원 공간 데이터를 빠르게 조회하기 위해 만든 2차원 인덱싱 방법으로


2차원 인덱싱 방법에는 R-Tree, R*Tree 등이 있음



Node.js를 알아가기 전에 동기 방식 과 비동기 방식 에 대한 정~~~말 간단한 예시를 보고 들어 가는게 좋을것 같아


가져왔습니다.



동기 입출력 (블로킹, Blocking IO) 방식 


파일 기능(읽기요청) -> 파일준비 -> 파일 처리 -> 데이터 처리 -> 다른작업 진행

var contents = file.read('a.txt');

******************대기*****************

doShow(contents);

var result = doAdd(10,10);



비동기 입출력(논블록깅 입출력, Non-Blocking IO) 방식

파일 기능(읽기요청) -> 파일준비 > 파일 처리 > 데이터 처리 

-> 다른작업 진행

file.read('a.txt',function(contents){

doShow(contents);

}

var result = doAdd(10,10);


|       Node Program                 |

|JavaScript C/C++                           |

| 노드 표준 라이브러리 |

| Node Standard library |

| 노드바인딩 |

| (Socket,http,etc) |

|스레드 풀 이벤트 루프  DNS crypto |

|libeio  libev    |

| V8 엔진 |

프로그램 실행시 V8엔진 위에서 실행됩니다. V8엔진 에서는 필요한 기능을 병렬로 실행하는 '스레드 풀'과

이벤트를 받아 처리하는 '이벤트 루프' 등의 기본 기능이 있으며 그 위에 네트워킹 기능을 담당하는 소켓(Socket)

,http 라이브러리 들이 있고 그 위에 표준 라이브러리가 구현되어있습니다.


결론 

특정 예시 [ 깍돌이의 오늘 저녁은 짜파게티위에 계란 후라이를 올려 먹을 생각입니다. ]

1. 짜파게티를 끓여야 함. [ 냄비에 물 올리고 끓으면 면넣고 섞어서 물 버리고 스프 로 섞기 ]

2. 계란후라이도 해야 함. [ 후라이팬에 불 달구고 기름 넣고 날계란 까서 뒤집어 주기 ]


이 두개의 작업이 있다고 하였을 때


동기 방식 


 후라이를 하든지 짜파게티를 끓이던지 하나를 정해야 합니다. 전자의 작업을 먼저 한다고 하였을 때 


1. 후라이팬을 꺼내 불 온도를 올립니다.

2. 온도가 올랐을때 기름을 붓고 날계란을 올립니다.

3. 익으면 뒤집어 줍니다.

[후라이 완료] - 예상 시간 60초


1. 냄비를 꺼내서 물을 넣고 끓입니다.

2. 끓었을때 짜파게티 사리를 넣습니다.

3. 익었을 경우 면을 섞고 물을 버립니다.

4. 스프를 넣고 섞습니다.

[짜파게티 완료] 예상 시간 150초


짜파게티 위에 계란을 올려 먹습니다.


-> 결과적으로 최소한 210초가 걸리게 되는 현상이 발생합니다.  하나씩 하나씩 스텝을 진행하여야 되기 때문입니다.


말로만 이렇게 하긴 했지만 프로그램적으로 봤을때는 짜파게티가 되기전 계란 후라이 작업에서는 펜딩되어있다고 보실


수 있기 때문에 매우 비효율적으로 보입니다. 


그러면 비동기가 짱짱일거 같지만 비동기가 매우 편리하고 좋지만 처리해야 할 작업도 많고


동기로 처리해야 하는경우가 있긴 합니다. 




비동기 방식  Node.js 의 논블로킹방식

(비동기는 실행순서가 늦는점을 이야기한거고 아래와 같은 예시는 논블로킹방식이 맞습니다.)


1. 후라이를 시작함과 동시에 냄비도 올리고 짜파게티도 시작합니다.

2. [후라이 완료] 60초 

3. [짜파게티 완료] 150초


짜파게티 위에 계란을 올려 먹습니다.


-> 결과적으로 동시에 따로 시작했고 후라이가 먼저 되었기 때문에 그걸 알려주게되며 전체 시간은 150초가 걸렸습니다.


위의 동기 방식을 더 쉽게 이야기하면 가스렌지가 1개 밖에 없어서 순차적으로 음식을만들어야 되는 점 


비동기 방식은 가스렌지가 2개라서 같이 진행 할수 있습니다.


어느정도 이해가 된 상태에서 비동기에 대한 포스팅은 다시 한번 자세하게 하겠습니다.








기존에 작성은 한적 있지만

 

새 서버로 옮기는 바람에 Node를 다시 설치 하여야 할 일이 생겼습니다.


노드 프로젝트를 통채로 가져왔기 때문에 


package.json 이랑 package-lock.json 은 그대로 있는 상태에서


Node를 재설치 후에 동작을 확인해보겠습니다.


우선 node.js 공식 홈페이지 접속 


https://nodejs.org/en/



메인 메뉴에서  DOWNLOADS 후  하단 


을 선택 합니다. 


저는 CentOS7 이기 때문에 엔터프라이즈 리눅스 메뉴를 선택


그리고 가이드대로 설치 합니다.


On RHEL, CentOS or Fedora, for Node.js v8 LTS:

curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -

Alternatively for Node.js 10:

curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -

Then install:

sudo yum -y install nodejs


현재 LTS버전인 8 (stable)  은 위에 LTS버전인 current 버전은 아래의 setup_10.x로 설치합니다.


설치 후  아래의 명령 yum -y install nodejs로 node를 설치합니다. node -v 로 버전 확인



설치가 잘됐습니다.


npm init으로 package.json 에 맞게 세팅 해주고


nodemon pm2같은 모듈은 제가 -g로 설정하여서 pakcage.json 에 없다보니


다시 재설치를 하였습니다.







NPM(Node Package Manager) 에 대해서는 이제 어떤건지 대략적으로 알수 있을 것 같습니다.


이제부터는 NPM 에서 사용하였던 모듈들에 대해서 리스트를 작성 하도록 할려고 합니다.


이번에는 2번째 모듈인  cors (Cross Origin Resource Sharing)  모듈에 대해서 간단하게 보려고 합니다.


왜 두번째로 cors를 하였냐면 가장 맨 처음에 부딪치는 이슈이기 때문입니다. 


122.118.155.163:3000 으로 node서버를 진행시


122.118.155.163 에서 node 실행 인데 3000 port로 Listen 중 이며



122.118.155.163:8888 에서 웹서버가 디플로이 (Deploy) 된 상태 에서 클라이언트가 


122.118.155.163 으로 ajax 요청을 보내게되면 크로스 도메인 이슈가 나타나게 된다.


웹서버(웹프로젝트)는 8888에 떠있지만 실제로 요청을 받는 API 서버는 3000 포트에서 받고 있기 때문이다. 


해당 크로스 도메인에 대해서는 따로 찾아 보시길 바라고 해당 의 경우에는 


3000으로 Listen 중인 이 서버가 같은 IP를 사용하고 있지라도 CORS 문제로 인해서 restapi 를 사용할수가 없게 된다. - 보안 상의 이유로 안된다고 하는데 해당 사항에 대해서는 찾아서 이 글에 수정 하도록 하겠습니다.



XMLHttpRequest cannot load http://xx.xx.xx.xx/xxx. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 

출처: http://blog.opid.kr/430 [opid's document]

해당 에러 메시지 가 나타났을 경우에 CORS 이슈가 나타났다고 할수 있습니다.


** IE에서 간혹 cors를 설정 하였는데도 불구하고 SEC7118 XMLHttpRequest CORS 라는 에러를 내 뿜는


경우가 있는데 해당은 IE 11 버그입니다. (Windows 10 으로 가서 실행시는 나타나지 않는)


CORS이슈가있으면 response, request가 되지 않습니다. 



이에 대해서 여러가지 방법이 있는데 

1. ajax의 dataType을 jsonp 로 바꾸는 법 


2. 헤더의 크로스 도메인 을 허가하는 방법 

  -> PHP  header("Access-Control-Allow-Origin: *");

  -> JSP  <% response.addHeader("Access-Control-Allow-Origin","*"); %>



3.  Node에서는 cors 모듈을 설치 하는 법

현재는 NPM에 대한 이야기 이므로  cors 모듈을 설치하여서 해결하는 방법이 있습니다.

express-cors 도있고 cors도 있는데  express-cors는 npm 검색시에도 잘 나오지 않고 npm에서 cors로 검색시에 가장 인기가 많은 cors 모듈을 사용하였으니 해당 모듈에 대해서 간단하게 

소개하겠습니다.


cors 검색하게되면 가장 상단에 


Node.js CORS middleware 2.8.4 가 보일 겁니다. 해당 클릭 

설명에 보시면  Connect/Express middleware that can be used to enable CORS with various options.


cors를 활성화 해준다고 되어있습니다. 여러 기능도 포함하여서


설치

-> npm 모듈이기 때문에 npm 으로 설치 합니다. 해당 설명도 진행할수록 생략 하도록 하겠습니다.


npm install cors


사용

npm cors 페이지 참조 

1. 모든 도메인 요청 활성화(모든 작업 CORS 허용 테스트용)

// 익스프레스 모듈 require 및 app 설정 (해당 방식은 express 에서 사용하도록 한 규약? 같은 방식)

var express = require('express')

var app =express();

// install cors 로 설치 하였기 때문에 cors 모듈 require

var cors = require('cors')


// cors () 사용  // 모든 도메인에 대한 Request 활성화  -> 좋지 않은 방식 

app.use(cors());


사용

2. 싱글 라우트에 대한 도메인 활성화(특정 작업에 대해서만 CORS허용)

// 익스프레스 사용

var express = require('express');

var app = express();


// cors 사용

var cors = require('cors');


// ***********  products/:id 에 대한 url 라우팅시에만  cors 를 허용 

app.get('/products/:id', cors(), function(req,res,next) {

res.json({msg:'This is CORS-enabled for a single Route'});

})


사용

3. CORS Config settings(setting 값을 수정하여서 CORS 허용 IP지정)

var express = require('express');

var app = expresS();


var corsOptions = {

origin :'http://example.com',

optionsSuccessStatus:200; // IE 11이나 여러 스마트 TV들에 대한 확인 

};


app.get('/products/:id',cors(corsOptions),function(req,res,next){

res.json({msg:' This is CORS-enabled for only example.com.'});

});

사용

4. CORS w/ Dynamic Origin  동적으로 읽어서 사용 

whitelist 배열을 push 로 추가하여서 실시간으로 허용 및 제거 가능 


// 앞 부분 생략


var whitelist = ['http://example1.com','http://example2.com']

var corsOptions = {

origin: function(origin,callback)    {

if(whitelist.indexOf(origin) !==-1){

callback (null,true);

} else{

callback (new Error('Not allowed by CORS'))

}

}

}


app.get('/products/:id', cors(corsOptions),function(req,res,next){

res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})

});


5. ETC CORS pre-Flight  CORS 비동기 사용 , CORS 제거 등에 대한 내용은

www.npmjs.com 에 cors 검색 후 확인 하시면 될것 같습니다.












NPM (Node Package Manager) 노드에서 사용하는 패키지 


uglify-js : 경량화 도구로써 자바스크립트 코드에 대해 공백을 제거하거나 코드를 가볍게 만들어줌


우선 www.npmjs.com 에 접속 



find packages 에 uglify-js 검색 


검색 후 리스트 중 최상단에 uglify-js (alexlamsl) // JavaScript parser, mangler/compressor and beautifier toolkit 클릭


안에 설명에 따른 설치를 보면


npm install uglify-js -g


또는


npm install uglify-js 로 설치를 할수 있으며


**ps -g옵션은 글로벌이란 뜻으로 어느 위치에서나 해당 명령어를 사용할수 있게 해주는 옵션 


( centos 기준으로  bash_profile에 넣어서 처리를 해주는게 아닌가 싶음 *추측 -> 확인되는 대로 글 수정 예정 )



-g 가 없을 시에는 lcoal 로 되며 현재 프로젝트 안에서만 사용이 가능 하다 



설치 후에 사용은 uglifyjs [input files] [option] 으로 사용한다고 적혀있다.



npm install uglify-js -g 로 설치 한 후에


uglifyjs 로 명령으로 실행하기전에 text.js를 생성


ugly.js


function ugly(ugly)

{

console.log("ugly");

console.log(ugly);

}

ugly("text Ugly");



와같이 작성후  (ESC 누른후 :  wq 엔터 -> vi 저장 단축키)


node ugly.js 실행시 다음과 같은 화면이 나타남 




이제 uglifyjs ugly.js 실행



 해당  입력이 위와같이 변함을 확인 할 수 있다. 


-m 옵션을 써서 uglifyjs ugly.js -m 을 써 주게 되면


위의 Local 변수인 ugly -> l 로 변환됨을 할수 있다. 이러한 변수명 까지 수정해준다.


새로운 파일로 추출해내기 위해서는


uglifyjs ugly.js -o ugly.min.js  와 같이 입력시 


ugliy.min.js 로 나타남을 확인 


해당 옵션을 같이 써서


uglifyjs ugly.js -m -o ugly.min.js 로 하게 되면 Local 변수로 수정하면서 다른 파일로 추출이 됨을 확인할수 있다.


+ Recent posts