0

我不知道如何通过 angular $http 发布。为什么?我想 multer 解析和存储我的文件和角度,以便在完成后获取副本。更好的是,我很乐意让 angular 获取一个副本,然后将其传递给服务器。

我可以使用以下代码段上传文件:

// view (jade)
.container
  form(action="/upload", method="POST", enctype="multipart/form-data")
    input(type="file", name="f")
    input(type="submit", value="Upload")

// post route (express)
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('f'), function(req, res) {
  console.log(req.file);
});

使用任何示例文件运行它,将我想要的 json 返回到控制台,并且图像成功存储在正确的目录中。然而:

// view (jade)
form(enctype="multipart/form-data" ng-submit="uploadFile(file)")
input(type="file", name="f", ng-model="file")
input(type="submit", value="Upload")

// ctrl (angular)
$scope.uploadFile = function(file) {
  console.log(file);
  $http.post('/upload', file);
};

// post route (express)
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('f'), function(req, res) {
  console.log(req.file);
});

这会在两个控制台输入上返回 undefined,即使我没有更改文件,我只是更改了它的发送方式。

这让我两个相信两件事之一:

提交的数据不是我想的那样。如果是这样,那是什么?日志上没有任何内容。

或者

提交的数据以某种方式被角度改变。如果是这种情况,怎么办?日志上再次没有打印任何内容。

4

1 回答 1

2

在第一种情况下,通过将数据直接通过表单发送到服务器,您可以让 html 在后台执行转换魔法。

在第二种情况下,通过 $http 通过 AngularJs 发布,您需要告诉中间件 $http,它需要对请求进行所需的转换以匹配您传递给表单的属性。

由于我自己为此苦苦挣扎了一段时间,这里是我使用的代码的改编版(用于 $resource)。但我认为它应该适用于它的底层 $http。

所以在你的控制器中:

$scope.uploadFile = function(file) {
   console.log(file);
   var fd = new FormData();
    fd.append('file', file);
    $http.post(uploadUrl, fd, {
        transformRequest: angular.identity,
        headers: {
            'Content-Type': undefined},
            enctype: 'multipart/form-data'
        }
     })
    .success(function(){
    })
    .error(function(){
    });   
 };

为此,您需要将文件输入字段绑定到模型。当然,Angularjs 出于某些原因选择不原生地这样做。

玉观中:

form(enctype="multipart/form-data" ng-submit....)
  input(type="file", name="f", ng-model="file" on change='angular.element(this).scope().readFile(this)')
  input(type="submit", value="Upload")

onchange是 JavaScript 而不是 AngularJs,它触发了我们需要定义的 scope.readfile() 函数:

在控制器中:

$scope.readfile = function(elem) {
    var file= elem.files[0];
    var reader = new FileReader();
   reader.onload = function() {
       $scope.$apply(function(){
           $scope.file = file;
           $scope.imageUrl = reader.result // to display         image via ng-Src
       })
   }
   reader.readAsDataURL(file);
}

我认为在处理表单时应该将一些 html 魔法带回角度。

我建议您查看 JavaScript 的onchange, FormData, 和FileReader类似的代码片段和更好的文档。

于 2015-10-30T15:46:45.527 回答