这是我的HTML表单:
<form name="myForm" ng-submit="">
<input ng-model='file' type="file"/>
<input type="submit" value='Submit'/>
</form>
我想从本地机器上传一个图像,并想读取上传文件的内容。所有这些我都想用AngularJS来做。
当我试图打印$scope的值时。文件是未定义的。
这是我的HTML表单:
<form name="myForm" ng-submit="">
<input ng-model='file' type="file"/>
<input type="submit" value='Submit'/>
</form>
我想从本地机器上传一个图像,并想读取上传文件的内容。所有这些我都想用AngularJS来做。
当我试图打印$scope的值时。文件是未定义的。
当前回答
我能够通过使用下面的代码使用AngularJS上传文件:
函数ngUploadFileUpload需要传递的参数的文件是$scope。按你的问题归档。
这里的关键点是使用transformRequest:[]。这将防止$http与文件内容混淆。
function getFileBuffer(file) {
var deferred = new $q.defer();
var reader = new FileReader();
reader.onloadend = function (e) {
deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise;
}
function ngUploadFileUpload(endPointUrl, file) {
var deferred = new $q.defer();
getFileBuffer(file).then(function (arrayBuffer) {
$http({
method: 'POST',
url: endPointUrl,
headers: {
"accept": "application/json;odata=verbose",
'X-RequestDigest': spContext.securityValidation,
"content-length": arrayBuffer.byteLength
},
data: arrayBuffer,
transformRequest: []
}).then(function (data) {
deferred.resolve(data);
}, function (error) {
deferred.reject(error);
console.error("Error", error)
});
}, function (error) {
console.error("Error", error)
});
return deferred.promise;
}
其他回答
您可以考虑使用IaaS进行文件上传,例如Uploadcare。有一个针对它的Angular包:https://github.com/uploadcare/angular-uploadcare
从技术上讲,它被实现为一个指令,提供了不同的上传选项,以及小部件中上传图像的操作:
<uploadcare-widget
ng-model="object.image.info.uuid"
data-public-key="YOURKEYHERE"
data-locale="en"
data-tabs="file url"
data-images-only="true"
data-path-value="true"
data-preview-step="true"
data-clearable="true"
data-multiple="false"
data-crop="400:200"
on-upload-complete="onUCUploadComplete(info)"
on-widget-ready="onUCWidgetReady(widget)"
value="{{ object.image.info.cdnUrl }}"
/>
更多配置选项:https://uploadcare.com/widget/configure/
最简单的是使用HTML5 API,即FileReader
HTML非常简单:
<input type="file" id="file" name="file"/>
<button ng-click="add()">Add</button>
在你的控制器中定义'add'方法:
$scope.add = function() {
var f = document.getElementById('file').files[0],
r = new FileReader();
r.onloadend = function(e) {
var data = e.target.result;
//send your binary data via $http or $resource or do anything else with it
}
r.readAsBinaryString(f);
}
浏览器兼容性
桌面浏览器
Edge 12, Firefox(Gecko) 3.6(1.9.2), Chrome 7, Opera* 12.02, Safari 6.0.2
移动浏览器
Firefox(壁虎)32, Chrome 3, 歌剧* 11.5, Safari 6.1
注意:readAsBinaryString()方法已弃用,应该使用readAsArrayBuffer()代替。
简单的指令
Html:
<input type="file" file-upload multiple/>
JS:
app.directive('fileUpload', function () {
return {
scope: true, //create a new scope
link: function (scope, el, attrs) {
el.bind('change', function (event) {
var files = event.target.files;
//iterate files since 'multiple' may be specified on the element
for (var i = 0;i<files.length;i++) {
//emit event upward
scope.$emit("fileSelected", { file: files[i] });
}
});
}
};
在指令中,我们确保创建了一个新的作用域,然后监听对文件输入元素所做的更改。当检测到更改时,以文件对象作为参数向所有祖先作用域(向上)发出事件。
在你的控制器中:
$scope.files = [];
//listen for the file selected event
$scope.$on("fileSelected", function (event, args) {
$scope.$apply(function () {
//add the file object to the scope's files collection
$scope.files.push(args.file);
});
});
然后在ajax调用中:
data: { model: $scope.model, files: $scope.files }
http://shazwazza.com/post/uploading-files-and-json-data-in-the-same-request-with-angular-js/
我想这是angular文件的上传:
ng-file-upload
用来上传文件的轻量级Angular JS指令。
这里是演示页面。特性
Supports upload progress, cancel/abort upload while in progress, File drag and drop (html5), Directory drag and drop (webkit), CORS, PUT(html5)/POST methods, validation of file type and size, show preview of selected images/audio/videos. Cross browser file upload and FileReader (HTML5 and non-HTML5) with Flash polyfill FileAPI. Allows client side validation/modification before uploading the file Direct upload to db services CouchDB, imgur, etc... with file's content type using Upload.http(). This enables progress event for angular http POST/PUT requests. Seperate shim file, FileAPI files are loaded on demand for non-HTML5 code meaning no extra load/code if you just need HTML5 support. Lightweight using regular $http to upload (with shim for non-HTML5 browsers) so all angular $http features are available
https://github.com/danialfarid/ng-file-upload
这里的一些答案建议使用FormData(),但不幸的是,这是一个浏览器对象,在Internet Explorer 9及以下版本中不可用。如果您需要支持这些旧浏览器,您将需要一个备份策略,例如使用<iframe>或Flash。
已经有很多Angular.js模块来执行文件上传。这两种浏览器都明确支持旧浏览器:
https://github.com/leon/angular-upload -使用iframes作为备份 https://github.com/danialfarid/ng-file-upload -使用FileAPI/Flash作为备份
还有一些其他的选择:
https://github.com/nervgh/angular-file-upload/ https://github.com/uor/angular-file https://github.com/twilson63/ngUpload https://github.com/uploadcare/angular-uploadcare
其中一个应该适合你的项目,或者可能会给你一些关于如何自己编写代码的见解。