AngularJS: 如何实现一个简单的文件上传与多部分形式?

我想做一个简单的多部分形式的帖子,从 AngularJS 到一个 node.js 服务器, 表单的一部分应该包含一个 JSON 对象,另一部分应该包含一个图像, (我目前只发布带有 $resource 的 JSON 对象)

我想我应该从 input type = “ file”开始,但是后来发现 AngularJS 不能绑定到这个. 。

我能找到的所有例子都是用来包装用于拖放的 jQuery 插件。我想要一个文件的简单上传。

我是 AngularJS 的新手,对于编写自己的指令一点也不自在。

282427 次浏览

我只是有这个问题。所以有几种方法。第一种是新的浏览器支持

var formData = new FormData();

点击这个链接到一个博客,里面有关于 支持如何仅限于现代浏览器的信息,除此之外,它完全解决了这个问题。

否则,可以使用 target 属性将表单发布到 iframe。 发布表单时,确保将目标设置为 iframe,并将其 display 属性设置为 none。 目标是 iframe 的名称

希望这个能帮上忙

我只是写了一个简单的指令(从现有的一个当然)在 AngularJ 的一个简单的上传。

(确切的 jQuery 上传插件是 https://github.com/blueimp/jQuery-File-Upload)

一个使用 AngularJs 的简单上传器(使用 CORS 实现)

(虽然服务器端是用于 PHP 的,但也可以简单地更改它的节点)

一个真正可行的解决方案,除了 angularjs 没有其他依赖项(在1.0.6版中进行了测试)

Html

<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/>

Angularjs (1.0.6)不支持在“ input-file”标签上使用 超模,因此必须以“本机方式”传递用户的所有(最终)选定文件。

控制器

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


$http.post(uploadUrl, fd, {
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success( ...all right!... ).error( ..damn!... );


};

最酷的部分是 未定义内容类型和 转换请求: 角度,身份,它们在 $http 上提供了选择正确的“内容类型”和管理处理多部分数据时所需的边界的能力。

您可以使用简单/轻量级的 文件上传指令。 它支持拖放,文件进度和文件上传为非 HTML5浏览器与 FileAPI 闪光垫

<div ng-controller="MyCtrl">
<input type="file" ngf-select="onFileSelect($files)" multiple>
</div>

约翰逊:

//inject angular file upload directive.
angular.module('myApp', ['ngFileUpload']);


var MyCtrl = [ '$scope', 'Upload', function($scope, Upload) {
$scope.onFileSelect = function($files) {
Upload.upload({
url: 'my/upload/url',
file: $files,
}).progress(function(e) {
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});


}];

我知道这是一个后期条目,但我已经创建了一个简单的上传指令。你很快就能找到工作了!

<input type="file" multiple ng-simple-upload web-api-url="/api/post"
callback-fn="myCallback" />

Github 上的 ng-simple-load 更多信息,并提供了一个使用 Web API 的示例。

你可以通过 $resource将数据分配给资源 actions的 params 属性,如下所示:

$scope.uploadFile = function(files) {
var fdata = new FormData();
fdata.append("file", files[0]);


$resource('api/post/:id', { id: "@id" }, {
postWithFile: {
method: "POST",
data: fdata,
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}
}).postWithFile(fdata).$promise.then(function(response){
//successful
},function(error){
//error
});
};

直接发送文件效率更高。

Content-Type: multipart/form-dataBase64编码额外增加了33% 的开销。如果服务器支持它,它就是 更有效率地直接发送文件:

$scope.upload = function(url, file) {
var config = { headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
return $http.post(url, file, config);
};

当发送带有 文件对象的 POST 时,重要的是设置 'Content-Type': undefined。然后,XHR 发送方法将检测到 文件对象并自动设置内容类型。

若要发送多个文件,请参见 直接从 FileList 执行多个 $http.post请求


我想我应该从 input type = “ file”开始,但是后来发现 AngularJS 不能绑定到这个. 。

<input type=file>元素在默认情况下不与 N- 型号指令一起工作。它需要一个 自定义指令:

ng-model< a href = “ https://stackoverflow. com/a/43074638/5535245”> 1 < a href = “ https://stackoverflow. com/a/43074638/5535245”> 1 协同工作的“ select-ng-files”指令工作演示

angular.module("app",[]);


angular.module("app").directive("selectNgFiles", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<h1>AngularJS Input `type=file` Demo</h1>
    

<input type="file" select-ng-files ng-model="fileArray" multiple>
    

<h2>Files</h2>
<div ng-repeat="file in fileArray">
\{\{file.name}}
</div>
</body>


内容类型为 multipart/form-data$http.post

如果必须发送 multipart/form-data:

<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text"  ng-model="fdata.UserName">
<input type="text"  ng-model="fdata.FirstName">
<input type="file"  select-ng-files ng-model="filesArray" multiple>
<button type="submit" ng-click="upload()">save</button>
</form>
$scope.upload = function() {
var fd = new FormData();
fd.append("data", angular.toJson($scope.fdata));
for (i=0; i<$scope.filesArray.length; i++) {
fd.append("file"+i, $scope.filesArray[i]);
};


var config = { headers: {'Content-Type': undefined},
transformRequest: angular.identity
}
return $http.post(url, fd, config);
};

当发送带有 表单数据 API的 POST 时,重要的是设置 'Content-Type': undefined。然后,XHR 发送方法将检测到 FormData对象,并自动将内容类型头设置为 多部分/表格数据适当的界限