我想从AngularJS到node.js服务器做一个简单的多部分表单发布,表单的一部分应包含JSON对象,另一部分应包含图像(我目前仅使用$ resource发布JSON对象)
我以为我应该从输入type =“ file”开始,但是后来发现AngularJS无法绑定到该文件。
我可以找到的所有示例都是用于包装jQuery插件以进行拖放的。我想要一个文件的简单上传。
我是AngularJS的新手,对自己编写指令完全不满意。
我想从AngularJS到node.js服务器做一个简单的多部分表单发布,表单的一部分应包含JSON对象,另一部分应包含图像(我目前仅使用$ resource发布JSON对象)
我以为我应该从输入type =“ file”开始,但是后来发现AngularJS无法绑定到该文件。
我可以找到的所有示例都是用于包装jQuery插件以进行拖放的。我想要一个文件的简单上传。
我是AngularJS的新手,对自己编写指令完全不满意。
Answers:
一个真正有效的解决方案,除了angularjs之外没有其他依赖项(已通过v.1.0.6测试)
html
<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/>
Angularjs(1.0.6)在“ input-file”标签上不支持ng-model,因此您必须以“本机”方式进行操作,该方式会传递用户的所有(最终)选定文件。
控制者
$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!... );
};
最酷的部分是未定义的内容类型和transformRequest:angular.identity,它们使$ http能够选择正确的“内容类型”并管理处理多部分数据时所需的边界。
fd.append("file", files[0]); fd.append("file",files[1]); fd.append("name", "MyName")
您可以使用simple / lightweight ng-file-upload指令。对于具有FileAPI flash填充程序的非HTML5浏览器,它支持拖放,文件进度和文件上传
<div ng-controller="MyCtrl">
<input type="file" ngf-select="onFileSelect($files)" multiple>
</div>
JS:
//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);
});
}];
该编码的base64的Content-Type: multipart/form-data
增加了额外的33%的开销。如果服务器支持,则直接发送文件更为有效:
$scope.upload = function(url, file) {
var config = { headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
return $http.post(url, file, config);
};
发送带有File对象的POST时,进行设置很重要'Content-Type': undefined
。然后,XHR send方法将检测File对象并自动设置内容类型。
要发送多个文件,请参阅进行多次$http.post
从文件列表直接请求
我以为我应该从输入type =“ file”开始,但是后来发现AngularJS无法绑定到该文件。
<input type=file>
默认情况下,该元素不适用于ng-model指令。它需要一个自定义指令:
ng-model
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>
$http.post
内容类型 multipart/form-data
如果必须发送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);
};
使用FormData API发送POST时,进行设置很重要'Content-Type': undefined
。然后,XHR send方法将检测到FormData
对象,并自动将内容类型标头设置为具有适当边界的multipart / form-data。
filesInput
指令似乎不适用于Angular 1.6.7,我可以看到中的文件,ng-repeat
但$scope.variable
控制器中的文件为空白?也是您的示例使用的file-model
一个,另一个是files-input
select-ng-files
。使用AngularJS 1.7.2测试。
我刚遇到这个问题。因此,有几种方法。首先是新的浏览器支持
var formData = new FormData();
通过此链接可以访问博客,其中包含有关如何将支持仅限于现代浏览器的信息,但否则,它可以完全解决此问题。
否则,您可以使用target属性将表单发布到iframe。发布表单时,请确保将目标设置为iframe,并将其display属性设置为none。目标是iframe的名称。(请您知道。)
我希望这有帮助
我知道这是一个较晚的条目,但是我创建了一个简单的上载指令。您可以立即开始工作!
<input type="file" multiple ng-simple-upload web-api-url="/api/post"
callback-fn="myCallback" />
ng-simple-upload在Github 上提供更多示例,并提供使用Web API的示例。
您可以通过$resource
将数据分配给资源的params属性来通过进行上传,actions
如下所示:
$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
});
};
我只是为AngularJs中的一个简单的上传器编写了一个简单的指令(来自现有课程)。
(确切的jQuery上传器插件是https://github.com/blueimp/jQuery-File-Upload)
(尽管服务器端用于PHP,但是您也可以简单地更改它的节点)