10. Binary 파일(image, mp3, mov 등) 처리

이번에는 이미지나 mp3 와 같은 바이너리 파일을 서비스하는 방법을 알아보겠습니다. node.js에 대해 선행공부가 조금이라도 되신분은 express 와 같은 외부모듈을 사용하면 아주 쉽게 처리할 수 있다고 아실텐데, 사실 기본모듈만 사용해도 어렵지 않게 처리할 수 있습니다. 9장에서 html 파일을 서비스하는 방법을 공부했기 때문에 특별한 설명없이 바로 진행하겠습니다.

가. 이미지 파일 다운로드

먼저 사전준비 사항으로 이미지파일을 3개 정도 인터넷에서 다운로드 받아둡니다. (전 요즘 관심사인 랭글러를... ㅎ)

이미지 파일은 확장자가 다른 종류로 준비합니다. 저는 jeep.jpg, jeep2.jpg, jeep3.png 이렇게 3개 파일을 준비했습니다.

그리고 프로젝트 폴더아래에 images 라는 폴더를 새로 생성하고 3개의 파일을 복사합니다. 복사가 완료되면 폴더 구조는 아래 그림과 같이 될겁니다.

나. 소스코드 작성

이제 server_request_binary.js 파일을 생성하고 아래와 같이 입력합니다.
소스코드를 작성하기 전에 npm install mime 으로 mime 을 알아내기 위한 모듈을 설치해야 합니다.

npm install mime
  • server_request_binary.js
var http = require('http');
var url = require('url');
var fs = require('fs');

// 1. mime 모듈 추가. 서비스하려는 파일의 타입을 알아내기 위해서 필요
var mime = require('mime');

var server = http.createServer(function(request,response){

  var parsedUrl = url.parse(request.url);
  var resource = parsedUrl.pathname;

  // 2. 요청한 자원의 주소가 '/images/' 문자열로 시작하면
  if(resource.indexOf('/images/') == 0){
    // 3. 첫글자인 '/' 를 제외하고 경로를 imgPath 변수에 저장
    var imgPath = resource.substring(1);
    console.log('imgPath='+imgPath);
    // 4. 서비스 하려는 파일의 mime type
    var imgMime = mime.getType(imgPath); // lookup -> getType으로 변경됨
    console.log('mime='+imgMime);

    // 5. 해당 파일을 읽어 오는데 두번째 인자인 인코딩(utf-8) 값 없음
    fs.readFile(imgPath, function(error, data) {
      if(error){
        response.writeHead(500, {'Content-Type':'text/html'});
        response.end('500 Internal Server '+error);
      }else{
        // 6. Content-Type 에 4번에서 추출한 mime type 을 입력
        response.writeHead(200, {'Content-Type':imgMime});
        response.end(data);
      }
    });
  }else{
    response.writeHead(404, {'Content-Type':'text/html'});
    response.end('404 Page Not Found');
  }
});

server.listen(80, function(){
    console.log('Server is running...');
});

다. 실행 및 브라우저 확인

node server_request_binary 로 서버를 실행하고 브라우저에서 각각의 이미지를 요청해 봅니다. 확장자가 서로 다름에도 3개 파일 모두 정상적으로 서비스되는 것을 확인할 수 있습니다.

라. 소스코드 분석

1.이미지 파일이라고 하더라도 파일의 확장자에 따라 mime type 이 서로 다릅니다. 그래서 요청한 파일의 mime type 을 요청할 때 마다 확인하기 위해서 아래와 같이 mime 모듈을 require( ) 합니다.

var mime = require('mime');

2.클라이언트가 요청한 주소값이 '/images/' 로 시작하는지를 검사합니다. indexOf( 검색할문자열 ) 함수는 검색할 문자열이 몇번째 부터 시작하는지를 숫자값으로 리턴해줍니다. 검색할문자열이 없으면 -1을 리턴하게 되고, 첫글자 부터 시작하면 0을 리턴해 줍니다.

따라서 아래와 같이 코딩하면 주소의 시작이 '/images/' 로 시작할때만 if문 안의 블럭이 실행됩니다.

if(resource.indexOf('/images/') == 0){

3.요청한 서버URI가 '/' 문자열로 시작하기 때문에 '/images/xxx.jpg' 로 파일을 읽으면 서버의 root 디렉토리 부터 검색합니다. 현재 서버의 구조에서는 실행파일인 server_request_binary.js 파일 아래에 images 폴더가 존재하므로 첫번째 문자인 '/' 를 제거합니다. 또는 '/' 는 그대로 두고 문자열 앞에 '.' 을 붙혀서 현재 폴더를 가리킬 수도 있습니다.

var imgPath = resource.substring(1); // 또는 '.' + resource 로 작성해도 된다.

4.서비스 하려는 파일의 mime type을 가져옵니다. image 뿐만이 아니라 음원파일이나 동영상 파일도 확장자에 따라 mime type 이 다릅니다.

var imgMime = mime.getType(imgPath); //버전에 따른 getType 대신 lookup 함수를 지원한다

5.fs.readFile( ) 파일을 사용할 때 일반 텍스트 파일을 읽을 때와는 입력되는 파라미터의 개수가 다릅니다. 텍스트 파일은 두번째에 파일의 encoding 값(utf-8)이 들어가지만, binary 파일은 인코딩값이 없습니다.

fs.readFile(imgPath, function(error, data) {

6.전송하는 파일의 Content-Type에 4번에서 추출했던 mime type 값을 입력합니다. 그러면 전송하려는 파일의 type에 따라 항상 자동으로 값을 입력해 줄 수 있습니다.

response.writeHead(200, {'Content-Type':imgMime});

results matching ""

    No results matching ""