himetani's blog

備忘録など。

Node.jsのExpressでmultipart/form-dataを処理する方法

ExpressでPOSTで送信されたデータを受け取るときになかなかうまくいかなかったので書きました。

フロント:AngularJS
サーバ :Node.js、Express

やろうとしてたことはmultipart/form-dataのデータをアップロードしてました。


POSTでは、body部に送信するデータが詰め込まれているので、サーバ側ではbody部のデータをハンドリングする必要があります。

最初はbody-parserというモジュールを使っていたんですが、データが全然見えなくて結構長い間悩んでましたw

どうやらmultipart/form-dataを扱うためには、body−parserとは別のモジュールを使う必要があるらしいです。

body−parserのREADMEにはこう書いてありました。

Node.js body parsing middleware.  
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:  
busboy and connect-busboy  
multiparty and connect-multiparty  
formidable  
multer  
Other body parsers you might be interested in:  
body  
co-body

expressjs/body-parser · GitHub


ということで、multerというモジュールを使いました。

コードは以下のとおり。

var express = require('express');
var router = express.Router();
var multer = require('multer');

var app = express();

router.post('/', multer({ dest: 'uploads/'}), function(req, res, next) {    
    res.send(JSON.stringify('hoge'));
});

multerを使うと簡単にmultipart/form-dataを取り扱いできる。


expressjs/multer · GitHub


ちなみにAngularJSはこんな感じ。

$scope.uploadFile = function(files) {
        var fd = new FormData();
        //Take the first selected file
        fd.append("file", files[0]);
        fd.append("parent_id", parent_id);
        fd.append("storage_type", 1);

        console.log('parent_id = '+parent_id);
        
        //$http.post('/api/file/upload.json',
        $http.post('http://localhost:3000/upload',
            fd, 
            {
                headers: {'Content-Type': undefined },
                transformRequest: angular.identity
            }).
            success(function(data, status, headers, config) {
                console.log(data);
                console.log(status);
                console.log(headers());
                $scope.update();
                $modalInstance.close(); 
            }).
            error(function(data, status, headers, config) {
                $modalInstance.close(); 
            });
    };

一部抜粋なのでよくわからないかもですが、大事なのは
・FormDataオブジェクトを生成している
 (multipart/form−dataのデータで、HTMLのformタグのデータと同じ扱われ方をする)
・AngularJSのpostメソッドで送信している
・ headers: {'Content-Type': undefined },
  transformRequest: angular.identity
 の2行はお約束らしい。
詳しくは

Blog | Multipart/form-data File Upload with AngularJS | Uncorked Studios


こんな感じで、multipart/form-dataをサーバ側に送ってます。