这是我的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的值时。文件是未定义的。
当前回答
这里的一些答案建议使用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
其中一个应该适合你的项目,或者可能会给你一些关于如何自己编写代码的见解。
其他回答
您可以考虑使用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()代替。
<form id="csv_file_form" ng-submit="submit_import_csv()" method="POST" enctype="multipart/form-data">
<input ng-model='file' type="file"/>
<input type="submit" value='Submit'/>
</form>
在angularJS控制器中
$scope.submit_import_csv = function(){
var formData = new FormData(document.getElementById("csv_file_form"));
console.log(formData);
$.ajax({
url: "import",
type: 'POST',
data: formData,
mimeType:"multipart/form-data",
contentType: false,
cache: false,
processData:false,
success: function(result, textStatus, jqXHR)
{
console.log(result);
}
});
return false;
}
<input type=file>元素默认不使用ng-model指令。它需要一个自定义指令:
使用ng-model1的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="fileList" multiple> <h2>Files</h2> <div ng-repeat="file in fileList"> {{file.name}} </div> </body>
美元http。从FileList中post
$scope.upload = function(url, fileList) {
var config = { headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
var promises = fileList.map(function(file) {
return $http.post(url, file, config);
});
return $q.all(promises);
};
当发送带有File对象的POST时,重要的是设置'Content-Type': undefined。然后XHR发送方法将检测File对象并自动设置内容类型。
我已经阅读了所有的线程,HTML5 API解决方案看起来最好。但它会改变我的二进制文件,以一种我没有调查过的方式破坏它们。最适合我的解决方案是:
HTML:
<input type="file" id="msds" ng-model="msds" name="msds"/>
<button ng-click="msds_update()">
Upload
</button>
JS:
msds_update = function() {
var f = document.getElementById('msds').files[0],
r = new FileReader();
r.onloadend = function(e) {
var data = e.target.result;
console.log(data);
var fd = new FormData();
fd.append('file', data);
fd.append('file_name', f.name);
$http.post('server_handler.php', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
console.log('success');
})
.error(function(){
console.log('error');
});
};
r.readAsDataURL(f);
}
服务器端(PHP):
$file_content = $_POST['file'];
$file_content = substr($file_content,
strlen('data:text/plain;base64,'));
$file_content = base64_decode($file_content);