AngularJS : 멀티 파트 양식으로 간단한 파일 업로드를 구현하는 방법은 무엇입니까?
AngularJS에서 node.js 서버로 간단한 멀티 파트 양식 게시를하고 싶습니다. 양식에는 한 부분에는 JSON 객체가 있고 다른 부분에는 이미지가 있어야합니다 (현재는 $ resource로 JSON 객체 만 게시하고 있습니다)
input type = "file"로 시작해야한다고 생각했지만 AngularJS가 바인딩 할 수 없다는 것을 알았습니다.
내가 찾을 수있는 모든 예제는 드래그 앤 드롭을 위해 jQuery 플러그인을 래핑하는 것입니다. 하나의 파일을 간단하게 업로드하고 싶습니다.
나는 AngularJS를 처음 사용하고 내 지시문을 작성해도 전혀 편하지 않습니다.
angularjs 이외의 다른 종속성이없는 실제 작동 솔루션 (v.1.0.6으로 테스트)
html
<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/>
Angularjs (1.0.6) 는 "입력 파일"태그에서 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에 올바른 "컨텐츠 유형"을 선택하고 멀티 파트 데이터를 처리 할 때 필요한 경계를 관리 할 수있는 기능을 제공합니다.
단순 / 경량 ng-file-upload 지시문을 사용할 수 있습니다 . FileAPI 플래시 심으로 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);
});
}];
파일을 직접 보내는 것이 더 효율적입니다.
인코딩베이스 64 로는 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의 전송 방법은 다음 감지 File 객체를 자동으로 콘텐츠 형식을 설정합니다.
여러 파일을 보내려면 FileList에서 직접 여러 요청 수행을 참조하십시오.$http.post
input type = "file"로 시작해야한다고 생각했지만 AngularJS가 바인딩 할 수 없다는 것을 알았습니다.
이 <input type=file>
요소는 기본적으로 ng-model 지시문 과 함께 작동하지 않습니다 . 사용자 지정 지시문 이 필요합니다 .
Working Demo of "select-ng-files" Directive that Works with ng-model
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
with content type multipart/form-data
If one must send 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);
};
When sending a POST with the FormData API, it is important to set 'Content-Type': undefined
. The XHR send method will then detect the FormData
object and automatically set the content type header to multipart/form-data with the proper boundary.
I just had this issue. So there are a few approaches. The first is that new browsers support the
var formData = new FormData();
Follow this link to a blog with info about how support is limited to modern browsers but otherwise it totally solves this issue.
Otherwise you can post the form to an iframe using the target attribute. When you post the form be sure to set the target to an iframe with its display property set to none. The target is the name of the iframe. (Just so you know.)
I hope this helps
I know this is a late entry but I have created a simple upload directive. Which you can get working in no time!
<input type="file" multiple ng-simple-upload web-api-url="/api/post"
callback-fn="myCallback" />
ng-simple-upload more on Github with an example using Web API.
I just wrote a simple directive (from existing one ofcourse) for a simple uploader in AngularJs.
(The exact jQuery uploader plugin is https://github.com/blueimp/jQuery-File-Upload)
A Simple Uploader using AngularJs (with CORS Implementation)
(Though the server side is for PHP, you can simple change it node also)
You could upload via $resource
by assigning data to params attribute of resource actions
like so:
$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
});
};
'Programming' 카테고리의 다른 글
동일한 프로젝트에서 C # 및 VB 혼합 (0) | 2020.06.21 |
---|---|
array [100] = {0}은 어떻게 전체 배열을 0으로 설정합니까? (0) | 2020.06.20 |
ReSharper 약어 목록 : 어디서 수정할 수 있습니까? (0) | 2020.06.20 |
nosetests가 내 인쇄 명세서의 출력을 캡처하고 있습니다. (0) | 2020.06.20 |
Parallel.ForEach () 대 foreach (IEnumerable) (0) | 2020.06.20 |