直接发送文件效率更高。
Content-Type: multipart/form-data 的 base64 encoding 增加了 33% 的额外开销。如果服务器支持,直接发送文件效率更高:
$scope.upload = function(url, file) {
var config = { headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
return $http.post(url, file, config);
};
发送带有File object 的POST 时,设置'Content-Type': undefined 很重要。然后XHR send method 会检测到File object 并自动设置内容类型。
要发送多个文件,请参阅Doing Multiple $http.post Requests Directly from a FileList
我想我应该从 input type="file" 开始,但后来发现 AngularJS 不能绑定到那个..
<input type=file> 元素默认情况下不适用于ng-model directive。它需要一个custom directive:
与ng-model一起使用的“select-ng-files”指令的工作演示1
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 method 将检测FormData 对象并自动将内容类型标头设置为multipart/form-data 和proper boundary。