Expressファイルフォーム解析ミドルウェアMultierの概要


前言
Expressで最もよく使用するform解析ミドルウェアはbody-parserであるが、multipart/form-data型のフォームはサポートされていないことを明確に示している.
したがってbody-parserの公式文書には、multipart/form-data型のミドルウェアをサポートするいくつかのリンク、またはmultipart/form-data解析のみをサポートするミドルウェアリンクが提供されている.
名前&アドレス
週間ダウンロード
stars
busboy
426,278
1448
multipart
240,921
993
formidable
1,390,361
4735
multer
284,926
5860
統計は2018年12月26日まで
Multierはbusboyに依存するため、busboyの実際の直接ダウンロード数は28万減少するはずだ.multipart/form-dataタイプのフォームとは?
最も直感的な解釈は、ファイルのアップロードをサポートするformフォームです.JavaScriptで作成しない場合は、明示的なhtml宣言は次の通りです.

上記の例ののページにおける表示は、1つのボタンをクリックすることでファイル選択が可能となる.
次にinputはmultiple="multiple"の属性を追加することができ、このとき開いたファイル選択ボックスは複数選択ファイルを許可する.
以下の関係をまとめます.
  • 1個のnameは複数のファイル
  • に対応する
  • 1個のnameは1個のファイル
  • に対応する
  • 複数のnameは複数の単一ファイル
  • に対応する
  • 複数name対応複数ファイル
  • ちなみにmulter 中国語のドキュメントがあります.
    本文
    特長
  • multerはformがenctype="multipart/form-data"に設定フォームのみを解析する.
  • multerは、ストレージエンジン
  • をカスタマイズすることができる.
  • multerは、アップロードされた情報およびコンテンツをrequestオブジェクトにマウントします.
  • request.body保存テキスト内容
  • request.fileは、単一ファイル情報および対応コンテンツ(メモリ記憶モード)
  • を保存する.
  • request.filesは、複数のファイル情報および対応するコンテンツ(メモリ記憶モード)
  • を保存する.

    基本ワークフロー
  • マルチインスタンス
  • を作成
  • は、この例で提供する異なる方法を使用して、異なる機能のミドルウェア
  • を取得する.
  • は、対応するルーティングに入れる
  • である.
    単一ファイルインスタンスのアップロード
    MultierとExpressの導入
    const
        express = require('express'),
        multer = require('multer'),
        app = express();

    入力構成パラメータ
    const upload = multer({dest:'/uploads'});

    注意:destパラメータはファイル出力の位置を指定し、ファイル出力を詳細に指定し、保存する後に説明します.
    Multierミドルウェアを使用して単一のファイルを渡す
    app.get('/',(request,response)=>{
    
        console.log('get.request.body',request.body);
        console.log('get.request.file',request.file);
        console.log('get.request.files',request.files);
    
        response.send('
    '+ '
    '+ '
    '+ ''+ '
    ') }); app.post('/',upload.single('upload'),(request,response)=>{ console.log('post.request.body',request.body); console.log('post.request.file',request.file); console.log('post.request.files',request.files); response.redirect('/'); }); app.listen(8888,()=>{ console.log('express 8888 '); });

    この例では、ルートパスを傍受し、それぞれ2つの異なる要求方式を処理し、getに対してフォームに応答し、postに対してアップロードされたコンテンツを受け入れる.
    注意:upload.single('upload')はmulterにnameがuploadの単一ファイルであることを伝えることを意味する.
    注意:この例ではinputは複数選択可能である、つまりバックエンドがファイル数を1と指定するがページが複数アップロードされており、このときmulterはエラーを報告する.
    注意:destが指定したパスがupload/であると、ルートの下のuploadフォルダにファイルが保存されます.windowsシステムでは、このアプリケーションを実行するための対応するディスクの下、例えばF:\uploads\です.
    この例では、テキストの内容を記入するとともに、ファイルをアップロードし、出力結果は次のようになります.
    post.request.body { title: 'hello world' }
    post.request.file { fieldname: 'upload',
      originalname: '           Victoria.7z',
      encoding: '7bit',
      mimetype: 'application/octet-stream',
      destination: '/uploads',
      filename: '6bdfc0df998d72e6232d60f790f47ef8',
      path: '\\uploads\\6bdfc0df998d72e6232d60f790f47ef8',
      size: 1033375 }

    複数のファイルインスタンスをアップロード
    const
        express = require('express'),
        multer = require('multer'),
        app = express();
    
    const upload = multer({dest:'/uploads'});
    
    app.get('/',(request,response)=>{
    
        console.log('get.request.body',request.body);
        console.log('get.request.file',request.file);
        console.log('get.request.files',request.files);
    
        response.send('
    '+ '
    '+ '
    '+ // name input '
    '+ ''+ '
    ') }); app.post('/',upload.array('upload'),(request,response)=>{ // console.log('post.request.body',request.body); console.log('post.request.file',request.file); console.log('post.request.files',request.files); response.redirect('/'); }); app.listen(8888,()=>{ console.log('express 8888 '); });

    この例のフォームには2つの同名のnameがファイルタイプであるが、今回はarray方式で受け入れられ、コンソール出力内容は以下の通りである.
    post.request.body { title: 'hello world' }
    post.request.file undefined
    post.request.files [ { fieldname: 'upload',
        originalname: '           Victoria.7z',
        encoding: '7bit',
        mimetype: 'application/octet-stream',
        destination: '/uploads',
        filename: '71ed2ac4299d43a30f5c13892f33e51b',
        path: '\\uploads\\71ed2ac4299d43a30f5c13892f33e51b',
        size: 1033375 },
      { fieldname: 'upload',
        originalname: '      .txt',
        encoding: '7bit',
        mimetype: 'text/plain',
        destination: '/uploads',
        filename: '190bde8fcdd08d57648ffb243607ed9d',
        path: '\\uploads\\190bde8fcdd08d57648ffb243607ed9d',
        size: 218 } ]

    上記の例では1つのinputを削除する、残りのinputをmultipleの属性を追加して複数選択に使用し、ページで選択ファイルボックスで複数のファイルを選択するもスムーズに通過する.
    その他の方法
    上記のmulter.singleの方法以外にもいくつかの方法がある.
  • array(name:string,maxcount?:number)nameに基づいてアップロードファイルの最大個数を制限する
  • fields(fields:object)カスタム制限規則
  • none()テキスト情報のみ保持
  • any()は任意のタイプのパスを許可し、ファイル配列はreq.files
  • に保存されます.
    実際にはfieldsメソッドのパッケージと見なすことができます.ソースコードは次のとおりです.
    Multer.prototype.single = function (name) {
      return this._makeMiddleware([{ name: name, maxCount: 1 }], 'VALUE')
    }
    
    Multer.prototype.array = function (name, maxCount) {
      return this._makeMiddleware([{ name: name, maxCount: maxCount }], 'ARRAY')
    }
    
    Multer.prototype.fields = function (fields) {
      return this._makeMiddleware(fields, 'OBJECT')
    }
    
    Multer.prototype.none = function () {
      return this._makeMiddleware([], 'NONE')
    }
    
    Multer.prototype.any = function () {
      function setup () {
        return {
          limits: this.limits,
          preservePath: this.preservePath,
          storage: this.storage,
          fileFilter: this.fileFilter,
          fileStrategy: 'ARRAY'
        }
      }
    
      return makeMiddleware(setup.bind(this))
    }

    共通API一覧
    中国語ドキュメント:multer(opts)
    Multierはoptionsオブジェクトを受け入れ、最も基本的な属性はdestであり、Multierがアップロードファイルをどこに保存するかを教えます.optionsオブジェクトを省略すると、これらのファイルはメモリに保存され、ディスクに書き込まれません.
    名前の競合を避けるために、Multierはアップロードしたファイル名を変更します.この名前変更機能は、必要に応じてカスタマイズできます.
    以下はMultierに渡すことができるオプションです.
    Key
    Description dest or storage
    ファイルを保存する場所fileFilter
    ファイルフィルタ、どのファイルが受け入れられるかを制御limits
    アップロードされたデータの制限preservePath
    ファイル名を含む完全なファイルパスを保存fileFilter
    アップロードできるファイルとスキップすべきファイルを制御する関数を設定します.この関数は次のように表示されます.
    function fileFilter (req, file, cb) {
    
      //          `cb`  boolean  
      //           
    
      //       ,  `false`,   :
      cb(null, false)
    
      //       ,  `true`,   :
      cb(null, true)
    
      //      ,             :
      cb(new Error('I don\'t have a clue!'))
    
    }

    エラー処理メカニズム
    エラーが発生すると、multerはエラーをexpressに送信します.良いエラー表示ページ(义齿)を使用することができます.
    Multierが発行したエラーをキャプチャしたい場合は、ミドルウェアプログラムを自分で呼び出すことができます.Multierエラーをキャプチャしたい場合は、multerオブジェクトの下にあるMulterErrorクラス(err instanceof multer.MulterError)を使用します.
    var multer = require('multer')
    var upload = multer().single('avatar')
    
    app.post('/profile', function (req, res) {
      upload(req, res, function (err) {
        if (err instanceof multer.MulterError) {
          //     
        } else if (err) {
          //     
        }
    
        //     
      })
    })

    ディスクストレージエンジン(DiskStorage)
    ディスクストレージエンジンは、ファイルのストレージを制御できます.
    var storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })
    
    var upload = multer({ storage: storage })

    2つのオプションがあります.destinationfilenameです.ファイルの格納場所を決定するための関数です.destinationは、アップロードされたファイルがどのフォルダに格納されるべきかを決定するために使用される.string(例えば、'/tmp/uploads')を提供することもできる.destinationが設定されていない場合は、オペレーティングシステムのデフォルトの一時フォルダが使用されます.
    注意:destinationが関数である場合は、フォルダの作成を担当する必要があります.文字列を指定すると、multerはこのフォルダが作成されていることを確認します.filenameは、フォルダ内のファイル名の決定に使用される.filenameが設定されていない場合、各ファイルはランダムなファイル名に設定され、拡張子はありません.
    注意:Multierは拡張子を追加しません.プログラムは完全なファイル名を返す必要があります.
    各関数は、リクエストオブジェクト(req)とこのファイルに関する情報(file)を渡し、あなたの決定に役立ちます.
    注意req.bodyは、クライアントにフィールドおよびファイルをサーバに送信する順序に応じて、まだ完全に埋め込まれていない可能性があります.
    メモリストレージエンジン(MemoryStorage)
    メモリストレージエンジンは、メモリ内のBufferオブジェクトにファイルを格納します.オプションはありません.
    var storage = multer.memoryStorage()
    var upload = multer({ storage: storage })

    メモリストレージエンジンを使用すると、ファイル情報にはbufferフィールドが含まれ、ファイルデータ全体が含まれます.
    警告:メモリストレージを使用すると、非常に大きなファイルをアップロードしたり、非常に多くの小さなファイルをアップロードしたりすると、アプリケーションのメモリがオーバーフローします.
    filefilterとfilenameにはルーティングトリガの順序もあります
    const
        express = require('express'),
        multer = require('multer'),
        app = express();
    
    const storage = multer.diskStorage({
        destination:__dirname, //        
        filename(request,file,callback){
    
            console.log('filename:',file);
    
            callback(null,'newfilename');//          
        }
    });
    
    
    const upload = multer({
        dest:'/uploads',
        fileFilter(request,file,cb){
    
            console.log('fileFilter:',file);
    
            cb(null,true);
    
        },
        limits:{
            fileSize:100000 //          100000  
        },
        storage //         
    });

    最後にトリガーされる順序は次のとおりです.
  • filefilter
  • filename
  • 我々が定義したルーティング