express 파일 업로드 원리 및 구현

express 파일 업로드 의 원리 와 실현
  • 원리
  • formidable
  • multer
  • COS

  • 1.원리
    1.1 express 업로드 에 대해 알 고 싶다 면 nodejs 네 이 티 브 업로드 가 어떻게 이 루어 졌 는 지 살 펴 보 자.
    let server = require('http').Server(app);
    server.listen(3000);
    

    우선 express 가 원본 http 모듈 의 일부 기능 을 가지 도록
    body Parser 같은 미들웨어 를 사용 하지 마 세 요.
    app.post('/upload', async(req, res)=>{
      var postData =  '';
      req.on("data", function(postDataChunk) {  //            
          postData += postDataChunk;
    
      });
    
      req.on("end", function() {  //       
          console.log(postData);
          res.end('up success');
    
         // console.log('post data finish receiving: ' + postData );
      });

    다음 전단 에 post 요청 ajax form 폼 을 모 의 하면 됩 니 다.

    What is your name?


    postcontent-type="application/x-www-form-urlencoded" console.log`의 post Data 는 name=xxx 일 것 입 니 다.이때 일부 query string 과 같은 미들웨어 를 통 해 key value 수 치 를 분석 하여 body Parser 를 조작 하 는 데 편리 하도록 합 니 다.하지만 file 제출 에 대해 서 는 이렇게 놀 수 없다 는 약점 이 있 습 니 다!그럼 왜 그런 지 계속 봅 시다.enctype="application/x-www-form-urlencoded"enctype=multipart/form-data파일 을 추가 하여 제출 하고 zip 파일 을 준비 합 니 다.

    What is your name?
    What files are you sending?


    zip 파일 업로드 와 이름 입력 후 배경console.log의 postdata 는 대략 이렇게 길 어 요.
    ------WebKitFormBoundaryXKLAlaggDlZOVroE
    Content-Disposition: form-data; name="name"
    
    xxxx
    ------WebKitFormBoundaryXKLAlaggDlZOVroE
    Content-Disposition: form-data; name="file"; filename="wrap.zip"
    Content-Type: application/zip
    
    PK�����bL�y��}������wrap.jpgUT    ��]�Z�ϟZux���������PS��?�HBKh�:   ŀ�  �zG"      

    정말 무 섭 습 니 다.형식 은 사실 난 코드 를 제외 하고 규칙 적 입 니 다.WebKitForm Boundary 를 통 해 분할 되 고 머리 정보 설명 과 파일 내용 이 있 습 니 다.이 대표 적 인 것 이 무엇 인지 알 고 싶 으 시 면 전송 문 을 보 세 요.
    코드 를 개선 하여 name 필드 end 에서 파일 생 성 을 취소 합 니 다.
    req.on("end", function() {  //       
    
           fs.writeFile('./upload/sss.zip',postData,'binary',function(err){  //path       public/logo.png
               if(err){
                 console.log('    !')
                   res.end('up failed');
    
               }else{
                   console.log('    !')
                   res.end('up success');
               }
           })
    
    
          // console.log('post data finish receiving: ' + postData );
       });
    

    이 코드 의 목적 은 전단 의 zip 패 키 지 를 받 아들 여 서버 의 upload 파일 에 sss.zip 로 저장 하 는 것 입 니 다.분명히 운행 은 성 공 했 고 생 성 되 었 지만 더 블 클릭 으로 압축 을 풀 때 열 리 지 않 았 다.다음 zip 의 크기 를 보 니 분명히 변 화 를 보 냈 습 니 다.그 이 유 는 다른 것 도 데이터 체 에 들 어 갔 기 때 문 입 니 다.사실 간단 합 니 다.해석 미들웨어 가 하나 빠 졌 을 뿐 입 니 다.
    2.formidable
    formidable 은 분석 소프트웨어npm install아래 와var formidable = require('formidable')아래 입 니 다.
    app.post('/upload', async(req, res)=>{
    
        var form = new formidable.IncomingForm();
        form.uploadDir = "./upload";
        //form.keepExtensions = true;                         
    
        form.parse(req, function(err, fields, files) {
                res.writeHead(200, {'content-type': 'text/plain'});
                res.write('received upload:

    '); var tmpPath=files.file.path; // var fileName=files.file.name; fs.rename(tmpPath,path.resolve(form.uploadDir,fileName),function (err) { if(err){ console.log(' !') } else{ console.log(' !') } res.end(); }) });

    그리고 생 성 된 zip 파일 을 엽 니 다.이번에 정상적으로 압력 을 풀 수 있다 는 것 은 데이터 가 파괴 되 지 않 았 다 는 것 을 설명 한다.formidable 도 많은 이벤트 구동 api,예 를 들 어progresserror등 구체 적 으로 문 서 를 봅 니 다.
    여기에 업로드 파일 을 원래 이름 으로 저 장 했 습 니 다.실제 상황 에 따라 정의 합 니 다.
    3.Multer
    multer 는 express 가 공식 적 으로 추천 한 업로드 미들웨어 이다.formidable 과 차이 가 많 지 않 지만 공식 적 으로 보 내 는 가장 기본 적 인 업로드 입 니 다.github 에 적 혀 있 는 부분 이 있 습 니 다.가 보 셔 도 됩 니 다.제 설정 을 참고 하 셔 도 됩 니 다.
    let setMulter = require('../util/myMulter');
    
    //      
    router.post('/upload',  function (req, res, next)  {
    
      //                    
      var upload=setMulter('file',1);
    
      upload(req, res, function (err) {
    
             try {
                  if (err) throw err;
                  if(req.files.length==0) throw new  Error("       "); //                
                    
                  res.send(`      ,  :${req.files[0].url}`);
    
    
             }
             catch (err) {
                     console.log(err.message);
                     res.send(`      ,  :${err.message}`);
             }
       });
    });
    

    myMulter.js
    let path=require('path');
    let multer = require('multer');
    //api https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
    
    
    //      
    let dir=path.resolve(__dirname,'../upload');
    
    //  mimes-type
    const mimes = {
        '.png': 'image/png',
        '.gif': 'image/gif',
        '.jpg': 'image/jpeg',
        '.jpeg': 'image/jpeg',
        '.zip':'application/zip'
    };
    
    
    //    
    const storage = multer.diskStorage({
    
        //Note:           ,        ,            ,multer     
        destination: function (req, file, cb) {
            cb(null, dir);
        },
        //    MD5,   ,    ,         
        filename: function (req, file, cb) {
    
            var ext =(file.originalname).split('.').pop();
            cb(null, `${file.fieldname}-${Date.now()}.${ext}`);
        }
    });
    
    //     
    const fileFilter =function  (req, file, cb) {
    
        //           
        var test = Object.values(mimes).filter(function(type) {
            return type===file.mimetype;
        })
    
    
        //       ,  `true`,   :
        if(test){
            cb(null, true);
        }else{ //       ,  `false`,   :
    
            cb(new Error('file mimes not allow!'), false);
        }
    
    
    }
    
    //    
    const limits={
        fileSize:1024 * 1024 * 30
    };
    
    
    module.exports=function(opt) {
    
        return  multer({
            storage: storage,
            fileFilter:fileFilter,
            limits: limits,
        }).array(opt);
    };
    

    진도 표를 추가 하고 싶 으 시 면 이 걸 참고 하 세 요.
    4.COS
    일반적으로 일반 업로드 파일 은 클 라 우 드 서버 업 체 의 저장 공간 과 결합 하여 cdn 가속 과 데이터 백업 등 작업 을 편리 하 게 하고 블록 업 로드 를 지원 할 수 있 습 니 다.multer 도 지원 하지만 직접 써 야 합 니 다.multer/storage/disk.js 를 참고 하려 면 stream 의 개념 을 파악 해 야 합 니 다.handle File 은 대류 처리 입 니 다.특히 multer 가 보 낸file.stream읽 을 수 있 는 흐름 은stream.Readable을 바탕 으로 스스로 고 친 것 입 니 다.fs.createReadStream()방법 은 읽 을 수 없 기 때문에 tmp 파일 을 만 들 고 읽 은 다음 에 삭제 해 야 합 니 다.저 는 텐 센트 클 라 우 드 코스 를 쓰 고 있 습 니 다.관심 있 으 시 면 보 세 요.https://github.com/lanbosm/multer-COS
    4.1 npm 패키지 설치npm install multer-cos -S4.2 자신의 multermy Multer.js 만 들 기
    let path=require('path');
    let multer = require('multer');
    let multerCOS = require('multer-cos');
    require( 'dotenv' ).config();
    /**
     * multer
     * https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
     * cos
     * https://cloud.tencent.com/document/product/436/12264#options-object
     */
    
    
    //      
    let dir=path.resolve(__dirname,'./tmp');
    
    //  mimes-type
    const mimes = {
        '.png': 'image/png',
        '.gif': 'image/gif',
        '.jpg': 'image/jpeg',
        '.jpeg': 'image/jpeg',
        '.zip':'application/zip',
        '.txt':'text/plain'
    };
    
    
    const cosConfig={
        //id key   
    
        //SecretId: AKIXXXXXXXXXXX,
        //SecretKey:XXXXXXXXXXXXXX,
        //Bucket:test-bucket-125XXXXXXXXX
        //Region=ap-shanghai
        //     
        FileParallelLimit: 3,    //          
        ChunkParallelLimit: 3,   //               
        ChunkSize: 1024 * 1024,  //       ,   B
        domain:'static.dorodoro-lab.com', //cos  
        dir:'upload',                     //cos    
        onProgress:function(progressData){//      ,       ,      
            //console.log(progressData);
        }
    
    };
    
    
    //    
    const storage = multerCOS({
        cos:cosConfig,
        //Note:           ,        ,            ,multer                     tmp  
        destination: function (req, file, cb) {
            cb(null, dir);
        },
        //        16         
        filename:'auto'
    });
    
    //  cos
    //storage.test();
    
    
    //     
    const fileFilter =function  (req, file, cb) {
    
        //           
        let test = Object.values(mimes).filter(type=>type===file.mimetype);
    
        //       ,  `true`,   :
        if(test.length>0){
            cb(null, true);
        }else{ //       ,  `false`,   :
            cb(new Error('file mimes not allow!'), false);
        }
    };
    
    //    
    const limits={
        fileSize:1024 * 1024 * 30
    };
    
    
    module.exports=function(opt) {
        return  multer({
            storage: storage,
            fileFilter:fileFilter,
            limits: limits,
        }).array(opt);
    };

    4.3 공식 버 전과 똑 같이 사용 하면 됩 니 다.콘 솔 에 api 키 를 설정 하 는 것 을 기억 하 세 요.
    다음으로 전송:https://www.cnblogs.com/lanbosm/p/8531862.html

    좋은 웹페이지 즐겨찾기