如何在http POST请求中发送数据和文件(使用angularjs + expressjs)?

4

情况

我实现了文件上传。前端代码来自流行的教程。我通过服务发送POST请求:

myApp.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        
        $http.post(uploadUrl, fd, {
             transformRequest: angular.identity,
             headers: {'Content-Type': undefined}
        })
        
        .success(function(){
        })
       
        .error(function(){
         });
        }
    }]);

后端中 multer 的典型用法:

exports.postFile = function (req, res) {

    var storage = multer.diskStorage({ //multers disk storage settings
        destination: function (req, file, cb) {
            cb(null, '../documents/')
        },
        filename: function (req, file, cb) {
            cb(null, file.originalname)
        }
    });

    var upload = multer({ //multer settings
        storage: storage
    }).single('file');

    upload(req, res, function (err) {
        if (err) {
            res.json({error_code: 1, err_desc: err});
            return;
        }
        res.json({error_code: 0, err_desc: null});
    })

};

可以这样做。

问题

如何在同一POST请求中发送一些数据,比如字符串“additional info”?

我的尝试

我尝试在服务中添加数据,例如:

...
var fd = new FormData();
fd.append('file', file);
fd.append('model', 'additional info');

$http.post(uploadUrl, fd, {...})

看起来已经发送了,但我不知道如何在后端接收它。尝试在req中查找(但没有成功)。

3个回答

6

要在一个POST请求中发送数据(即json)和文件,请将两者都添加到表单数据中:

myApp.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);

        var info = {
            "text":"additional info"
        };
        fd.append('data', angular.toJson(info));

        $http.post(uploadUrl, fd, {
             transformRequest: angular.identity,
             headers: {'Content-Type': undefined}
        })

        .success(function(){
        })

        .error(function(){
        });
    }
}]);

服务器端数据存储在req.body.data中,可以通过以下方式接收:

upload(req, res, function (err) {
    if (err) {
        res.json({error_code: 1, err_desc: err});
        return;
    }

    console.log(req.body.data);

    res.json({error_code: 0, err_desc: null});
})

谢谢您提供这个有用的答案,解决了我的问题。 - r3wt

0

你可以从 req.files 获取文件,并使用 fs.writeFile 保存它。

fs.readFile(req.files.formInput.path, function (err, data) {
  fs.writeFile(newPath, data, function (err) {
    if (err) {
    throw err;
    }
    console.log("File Uploaded");
  });
});

我在发送和接收文件方面没有任何问题。它可以正常工作。我想在同一POST请求中发送(和接收)附加数据(以及文件)。 - Łukasz
你可以使用$data属性在$http.post中发送一个包含所有额外数据的对象,从而发送所有输入。 - Carlos Jafet Neto
我已经修改了第一个答案,展示如何从所有输入中传递数据,假设你的输入文件上有ng-model="user.email"等。 - Carlos Jafet Neto

-1
你可以像这样做:
          $http({
                url: url, 
                method: 'POST',
                data: json_data,
                headers: {'Content-Type': 'application/json'}
          }).then(function(response) {
                var res = response.data;
                console.log(res);
          }, function errorCallback(response) {
              // called asynchronously if an error occurs
             // or server returns response with an error status.
          });

或者只需将数据属性添加到您的函数中。

    var userObject = {
    email: $scope.user.email,
    password: $scope.user.password,
    fullName: $scope.user.fullName
    };

    $http.post(uploadUrl, fd, {
         transformRequest: angular.identity,
         data: userObject,
         headers: {'Content-Type': 'application/json'}
    })

你可以在后端尝试类似这样的东西。
req.on('data', function (chunk) {
    console.log(chunk);
});

1
这个POST请求中的文件在哪里? - Łukasz
你提供了一些字符串数据。 - Carlos Jafet Neto
我的意思是字符串和文件一起,就像标题所说的那样。 - Łukasz
关于最后一次编辑:为什么我要在服务器响应中查找它? - Łukasz
抱歉,是req.on。我会更改的。看一下第二个答案。希望这有所帮助! - Carlos Jafet Neto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接