使用 AngularJS 上传文件
Posted
技术标签:
【中文标题】使用 AngularJS 上传文件【英文标题】:File Upload using AngularJS 【发布时间】:2013-09-05 10:21:53 【问题描述】:这是我的 html 表单:
<form name="myForm" ng-submit="">
<input ng-model='file' type="file"/>
<input type="submit" value='Submit'/>
</form>
我想从本地机器上传一张图片,并想读取上传文件的内容。这一切我都想用 AngularJS 来完成。
当我尝试打印 $scope.file
的值时,它是未定义的。
【问题讨论】:
怎么样:***.com/questions/12979712/… 查看接受的答案stackoverrun.com/es/q/10211532#37040022。它使用FormData
和angular-file-model
。要了解如何使用file-model
,请参阅embed.plnkr.co/plunk/0ZHCsR。它对我有用。
【参考方案1】:
这里的一些答案建议使用FormData()
,但不幸的是,这是 Internet Explorer 9 及更低版本中不可用的浏览器对象。如果您需要支持那些较旧的浏览器,则需要一种备份策略,例如使用<iframe>
或 Flash。
已经有很多 Angular.js 模块来执行文件上传。这两个都明确支持旧版浏览器:
https://github.com/leon/angular-upload - 使用 iframe 作为后备 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):github.com/uploadcare/angular-uploadcare EggHead 有一个很好的视频 - egghead.io/lessons/angularjs-file-uploads danialfarid/angular-file-upload 重命名为 ng-file-upload 3 岁的答案。 IE 9 现在在 2016 年已经死了。 我认为您应该更新您的答案以获得正确的解决方案,而不是指向链接。这就是堆栈溢出的方式。否则,只需将其作为评论。【参考方案2】:最简单的就是使用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
移动浏览器
火狐(壁虎)32, 铬 3, 歌剧* 11.5, Safari 6.1
注意:readAsBinaryString() 方法已被弃用,而应使用readAsArrayBuffer()。
【讨论】:
FileReader 是标准 HTML5 文件 API w3.org/TR/FileAPI 中的一个类。它允许您从 html 输入元素中指定的文件中读取数据并在onloadend
回调函数中对其进行处理。您不需要任何库来使用此 API,它已经在您的浏览器中(除非您使用非常旧的库)。希望这会有所帮助。
FileReader.readAsBinaryString 已于 2012 年 7 月 12 日被 W3C 的工作草案弃用。
您不应该使用 Angular 访问 DOM。是一种非常糟糕的做法。
@Siderex,不在控制器中,但从指令中做到这一点非常棒。事实上,这就是指令的用途。您可以在 Angular 文档 docs.angularjs.org/guide/directive 中阅读有关它的信息
@yagger 为什么你的链接引用 FileReaderSync 的 readAsArrayBuffer
方法(仅在 web 工作者中可用)而不是常规的异步 FileReader API 是否有特殊原因?【参考方案3】:
这是现代浏览器方式,没有 3rd 方库。适用于所有最新的浏览器。
app.directive('myDirective', function (httpPostFactory)
return
restrict: 'A',
scope: true,
link: function (scope, element, attr)
element.bind('change', function ()
var formData = new FormData();
formData.append('file', element[0].files[0]);
httpPostFactory('upload_image.php', formData, function (callback)
// recieve image name to use in a ng-src
console.log(callback);
);
);
;
);
app.factory('httpPostFactory', function ($http)
return function (file, data, callback)
$http(
url: file,
method: "POST",
data: data,
headers: 'Content-Type': undefined
).success(function (response)
callback(response);
);
;
);
HTML:
<input data-my-Directive type="file" name="file">
PHP:
if (isset($_FILES['file']) && $_FILES['file']['error'] == 0)
// uploads image in the folder images
$temp = explode(".", $_FILES["file"]["name"]);
$newfilename = substr(md5(time()), 0, 10) . '.' . end($temp);
move_uploaded_file($_FILES['file']['tmp_name'], 'images/' . $newfilename);
// give callback to your angular code with the image src name
echo json_encode($newfilename);
js 小提琴(仅前端) https://jsfiddle.net/vince123/8d18tsey/31/
【讨论】:
如何获取节点中的文件? 还有更多细节吗?您需要ng-submit
或表单操作吗?这本身没有任何作用
@Emaborsa hello 我添加了一个 jsfiddle 并制作了一个更完整的 php 代码示例。它在文件输入的值发生更改后提交图像,因此不需要 ng-submit。
完美最简单的解决方案,但是我花了很长时间才弄清楚如何让我的 WCF 服务来处理正在上传的数据。您获取数据流并通过 MultiParser 之类的东西传递它以实际读取文件数据是 至关重要的:***.com/a/23702692/391605 否则您将存储“------”的原始字节WebKitFormBoundary Content-Disposition:... etc.."
我需要将属性 'transformRequest: angular.identity' 添加到 $http 请求对象,如 Manoy Ojha 所示,再往下一点,否则 Content-Type 将无法正确设置,示例将不起作用.【参考方案4】:
以下是文件上传的工作示例:
http://jsfiddle.net/vishalvasani/4hqVu/
在这个函数中调用
setFiles
从视图将更新控制器中的文件数组
或
您可以使用 AngularJS 检查 jQuery 文件上传
http://blueimp.github.io/jQuery-File-Upload/angularjs.html
【讨论】:
嗨,我正在寻找可以上传一个文件并显示在其下方的东西。但是在您的示例中,我无法做到这一点。不介意,但我是这个 angularjs 的新手,我打算学习以更简单但更强大的方式完成这个特定目标。 这很有帮助。谢谢! 不使用额外库/扩展的优秀示例。谢谢。 非常有帮助,只是一个注释..这使用了在 IE9 或更低版本中不起作用的 File API。 知道我是如何从结果中得到错误的吗?服务器可能会出错,我想显示该错误消息...【参考方案5】:您可以使用flow.js实现漂亮的文件和文件夹上传。
https://github.com/flowjs/ng-flow
在这里查看演示
http://flowjs.github.io/ng-flow/
它不支持IE7、IE8、IE9,所以你最终必须使用兼容层
https://github.com/flowjs/fusty-flow.js
【讨论】:
`flow.js' 很棒,但文档还很差。我需要操纵单个上传并添加预览并分开发送事件按钮,但我不知道该怎么做。【参考方案6】:使用onchange
事件将输入文件元素传递给您的函数。
<input type="file" onchange="angular.element(this).scope().fileSelected(this)" />
因此,当用户选择文件时,您无需点击“添加”或“上传”按钮即可获得对该文件的引用。
$scope.fileSelected = function (element)
var myFileSelected = element.files[0];
;
【讨论】:
这没有按预期工作。这是我的工作流程: 1. 刷新页面 2. 添加新文件。 ** 添加的第一个文件始终未定义。** 3. 添加另一个文件。从现在开始,每个上传的文件都是我之前添加的文件。所以对于我添加的第二个文件,这将上传我添加的第一个文件(实际上失败了) 最好的方法!【参考方案7】:我尝试了@Anoyz(正确答案)给出的所有替代方案......最好的解决方案是https://github.com/danialfarid/angular-file-upload
一些特点:
进展 多文件 字段 旧版浏览器 (IE8-9)这对我来说很好用。您只需要注意说明即可。
在服务器端,我使用 NodeJs、Express 4 和 Multer 中间件来管理多部分请求。
【讨论】:
如何显示图像?从后端,他们成功进入,但他们被保存为nlzt9LJWRrAZEO3ZteZUOgGc
但没有 .png 格式。如何添加?【参考方案8】:
HTML
<html>
<head></head>
<body ng-app = "myApp">
<form ng-controller = "myCtrl">
<input type = "file" file-model="files" multiple/>
<button ng-click = "uploadFile()">upload me</button>
<li ng-repeat="file in files">file.name</li>
</form>
脚本
<script src =
"http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
angular.module('myApp', []).directive('fileModel', ['$parse', function ($parse)
return
restrict: 'A',
link: function(scope, element, attrs)
element.bind('change', function()
$parse(attrs.fileModel).assign(scope,element[0].files)
scope.$apply();
);
;
]).controller('myCtrl', ['$scope', '$http', function($scope, $http)
$scope.uploadFile=function()
var fd=new FormData();
console.log($scope.files);
angular.forEach($scope.files,function(file)
fd.append('file',file);
);
$http.post('http://localhost:1337/mediaobject/upload',fd,
transformRequest: angular.identity,
headers: 'Content-Type': undefined
).success(function(d)
console.log(d);
)
]);
</script>
【讨论】:
【参考方案9】:<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="fileList" multiple>
<h2>Files</h2>
<div ng-repeat="file in fileList">
file.name
</div>
</body>
$http.post
来自 FileList
$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 object 的POST 时,设置'Content-Type': undefined
很重要。然后XHR send method 会检测File object 并自动设置内容类型。
【讨论】:
【参考方案10】:简单的指令
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/
【讨论】:
【参考方案11】:我认为这是 Angular 文件上传:
ng-文件上传
用于上传文件的轻量级 Angular JS 指令。
这是DEMO page.Features
支持上传进度、取消/中止上传、文件拖放 (html5)、目录拖放 (webkit)、CORS、PUT(html5)/POST 方法、文件类型和大小验证、显示预览选定的图像/音频/视频。 使用 Flash polyfill FileAPI 跨浏览器文件上传和 FileReader(HTML5 和非 HTML5)。允许在上传文件之前进行客户端验证/修改 使用 Upload.http() 将文件的内容类型直接上传到数据库服务 CouchDB、imgur 等。这将为 Angular http POST/PUT 请求启用进度事件。 单独的 shim 文件,FileAPI 文件按需加载非 HTML5 代码,这意味着如果您只需要 HTML5 支持,则无需额外加载/代码。 轻量级使用常规 $http 上传(对于非 HTML5 浏览器使用 shim),因此所有角度 $http 功能都可用https://github.com/danialfarid/ng-file-upload
【讨论】:
【参考方案12】:你的文件和json数据同时上传。
// FIRST SOLUTION
var _post = function (file, jsonData)
$http(
url: your url,
method: "POST",
headers: 'Content-Type': undefined ,
transformRequest: function (data)
var formData = new FormData();
formData.append("model", angular.toJson(data.model));
formData.append("file", data.files);
return formData;
,
data: model: jsonData, files: file
).then(function (response)
;
);
// END OF FIRST SOLUTION
// SECOND SOLUTION
// If you can add plural file and If above code give an error.
// You can try following code
var _post = function (file, jsonData)
$http(
url: your url,
method: "POST",
headers: 'Content-Type': undefined ,
transformRequest: function (data)
var formData = new FormData();
formData.append("model", angular.toJson(data.model));
for (var i = 0; i < data.files.length; i++)
// add each file to
// the form data and iteratively name them
formData.append("file" + i, data.files[i]);
return formData;
,
data: model: jsonData, files: file
).then(function (response)
;
);
// END OF SECOND SOLUTION
【讨论】:
【参考方案13】:您可以使用安全快速的FormData
对象:
// Store the file object when input field is changed
$scope.contentChanged = function(event)
if (!event.files.length)
return null;
$scope.content = new FormData();
$scope.content.append('fileUpload', event.files[0]);
$scope.$apply();
// Upload the file over HTTP
$scope.upload = function()
$http(
method: 'POST',
url: '/remote/url',
headers: 'Content-Type': undefined ,
data: $scope.content,
).success(function(response)
// Uploading complete
console.log('Request finished', response);
);
【讨论】:
能否请您解释一下“contentChanged”的具体使用位置? 当文件输入发生变化时,触发此功能将开始上传过程。 既然没有<input type="file" ng-change="contentChanged($event)">
,怎么办?【参考方案14】:
http://jsfiddle.net/vishalvasani/4hqVu/ 在 chrome 和 IE 中运行良好(如果您在 background-image 中稍微更新 CSS)。 这用于更新进度条:
scope.progress = Math.round(evt.loaded * 100 / evt.total)
但在 FireFox Angular 中,虽然文件上传成功,但 DOM 中的 [percent] 数据未成功更新。
【讨论】:
对于 FF,你可以监听load
事件,如果长度是可计算的,则触发进度事件以指示成功上传。 github.com/danialfarid/angular-file-upload 已经处理好了。
它在那里,但在给定的小提琴中,它也被检查和应用。 FF 仍然没有希望。
我认为如果你只是在 uploadComplete 中调用 uploadProgress 它应该适用于 FF
不,它没有,即使有,你能解释一下原因吗?我在我的帖子中给出了一个小提琴的链接。如果可能的话,您能否将其更新为在 FF 中工作并在此处评论解决方案的链接?
什么版本的火狐?【参考方案15】:
您可以考虑使用 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/
【讨论】:
【参考方案16】:我知道这是一个迟到的条目,但我创建了一个简单的上传指令。您可以立即开始工作!
<input type="file" multiple ng-simple-upload web-api-url="/api/Upload" callback-fn="myCallback" />
ng-simple-upload Github 上的更多内容,其中包含使用 Web API 的示例。
【讨论】:
【参考方案17】:HTML
<input type="file" id="file" name='file' onchange="angular.element(this).scope().profileimage(this)" />
将“profileimage()”方法添加到您的控制器
$scope.profileimage = function(selectimage)
console.log(selectimage.files[0]);
var selectfile=selectimage.files[0];
r = new FileReader();
r.onloadend = function (e)
debugger;
var data = e.target.result;
r.readAsBinaryString(selectfile);
【讨论】:
【参考方案18】:这应该是对@jquery-guru 答案的更新/评论,但由于我没有足够的代表,它会放在这里。它修复了现在由代码生成的错误。
https://jsfiddle.net/vzhrqotw/
变化基本是:
FileUploadCtrl.$inject = ['$scope']
function FileUploadCtrl(scope)
收件人:
app.controller('FileUploadCtrl', function($scope)
如果需要,请随意移动到更合适的位置。
【讨论】:
【参考方案19】:我已阅读所有主题,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);
【讨论】:
【参考方案20】:我可以通过以下代码使用 AngularJS 上传文件:
根据您的问题,需要为函数 ngUploadFileUpload
传递的参数的 file
是 $scope.file
。
这里的重点是使用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;
【讨论】:
【参考方案21】:以上接受的答案与浏览器不兼容。如果有人有兼容性问题,试试这个。
Fiddle
查看代码
<div ng-controller="MyCtrl">
<input type="file" id="file" name="file"/>
<br>
<button ng-click="add()">Add</button>
<p>data</p>
</div>
控制器代码
var myApp = angular.module('myApp',[]);
function MyCtrl($scope)
$scope.data = 'none';
$scope.add = function()
var f = document.getElementById('file').files[0],
r = new FileReader();
r.onloadend = function(e)
var binary = "";
var bytes = new Uint8Array(e.target.result);
var length = bytes.byteLength;
for (var i = 0; i < length; i++)
binary += String.fromCharCode(bytes[i]);
$scope.data = (binary).toString();
alert($scope.data);
r.readAsArrayBuffer(f);
【讨论】:
【参考方案22】:简单来说
在 Html 中 - 仅添加以下代码
<form name="upload" class="form" data-ng-submit="addFile()">
<input type="file" name="file" multiple
onchange="angular.element(this).scope().uploadedFile(this)" />
<button type="submit">Upload </button>
</form>
在控制器中 - 当您点击“上传文件按钮”时调用此函数。它将上传文件。你可以安慰它。
$scope.uploadedFile = function(element)
$scope.$apply(function($scope)
$scope.files = element.files;
);
在控制器中添加更多 - 下面的代码添加到函数中。当您单击使用 "hitting the api (POST)" 的按钮时,将调用此函数。它会将文件(上传的)和表单数据发送到后端。
var url = httpURL + "/reporttojson"
var files=$scope.files;
for ( var i = 0; i < files.length; i++)
var fd = new FormData();
angular.forEach(files,function(file)
fd.append('file',file);
);
var data =
msg : message,
sub : sub,
sendMail: sendMail,
selectUsersAcknowledge:false
;
fd.append("data", JSON.stringify(data));
$http.post(url, fd,
withCredentials : false,
headers :
'Content-Type' : undefined
,
transformRequest : angular.identity
).success(function(data)
toastr.success("Notification sent successfully","",timeOut: 2000);
$scope.removereport()
$timeout(function()
location.reload();
, 1000);
).error(function(data)
toastr.success("Error in Sending Notification","",timeOut: 2000);
$scope.removereport()
);
在这种情况下..我在下面添加了代码作为表单数据
var data =
msg : message,
sub : sub,
sendMail: sendMail,
selectUsersAcknowledge:false
;
【讨论】:
【参考方案23】:<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;
【讨论】:
【参考方案24】:我们使用了 HTML、CSS 和 AngularJS。以下示例展示了如何使用 AngularJS 上传文件。
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['$parse', function ($parse)
return
restrict: 'A',
link: function(scope, element, attrs)
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function()
scope.$apply(function()
modelSetter(scope, element[0].files[0]);
);
);
;
]);
myApp.service('fileUpload', ['$http', function ($http)
this.uploadFileToUrl = function(file, uploadUrl)
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd,
transformRequest: angular.identity,
headers: 'Content-Type': undefined
)
.success(function()
)
.error(function()
);
]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload)
$scope.uploadFile = function()
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
;
]);
</script>
</body>
</html>
【讨论】:
这来自TutorialsPoint,但至少你做了很好的纠正他们的例子,因为明显的错误甚至无法运行!【参考方案25】:工作示例使用简单指令(ng-file-model):
.directive("ngFileModel", [function ()
return
$scope:
ngFileModel: "="
,
link: function ($scope:any, element, attributes)
element.bind("change", function (changeEvent:any)
var reader = new FileReader();
reader.onload = function (loadEvent)
$scope.$apply(function ()
$scope.ngFileModel =
lastModified: changeEvent.target.files[0].lastModified,
lastModifiedDate: changeEvent.target.files[0].lastModifiedDate,
name: changeEvent.target.files[0].name,
size: changeEvent.target.files[0].size,
type: changeEvent.target.files[0].type,
data: changeEvent.target.files[0]
;
);
reader.readAsDataURL(changeEvent.target.files[0]);
);
])
并使用FormData
在您的函数中上传文件。
var formData = new FormData();
formData.append("document", $scope.ngFileModel.data)
formData.append("user_id", $scope.userId)
所有学分都用于 https://github.com/mistralworks/ng-file-model
我遇到了一个小问题,您可以在这里查看: https://github.com/mistralworks/ng-file-model/issues/7
最后,这是一个分叉的 repo:https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js
【讨论】:
【参考方案26】:代码将有助于插入文件
<body ng-app = "myApp">
<form ng-controller="insert_Ctrl" method="post" action="" name="myForm" enctype="multipart/form-data" novalidate>
<div>
<p><input type="file" ng-model="myFile" class="form-control" onchange="angular.element(this).scope().uploadedFile(this)">
<span style="color:red" ng-show="(myForm.myFile.$error.required&&myForm.myFile.$touched)">Select Picture</span>
</p>
</div>
<div>
<input type="button" name="submit" ng-click="uploadFile()" class="btn-primary" ng-disabled="myForm.myFile.$invalid" value="insert">
</div>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="insert.js"></script>
</body>
插入.js
var app = angular.module('myApp',[]);
app.service('uploadFile', ['$http','$window', function ($http,$window)
this.uploadFiletoServer = function(file,uploadUrl)
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd,
transformRequest: angular.identity,
headers: 'Content-Type': undefined
)
.success(function(data)
alert("insert successfull");
$window.location.href = ' ';//your window location
)
.error(function()
alert("Error");
);
]);
app.controller('insert_Ctrl', ['$scope', 'uploadFile', function($scope, uploadFile)
$scope.uploadFile = function()
$scope.myFile = $scope.files[0];
var file = $scope.myFile;
var url = "save_data.php";
uploadFile.uploadFiletoServer(file,url);
;
$scope.uploadedFile = function(element)
var reader = new FileReader();
reader.onload = function(event)
$scope.$apply(function($scope)
$scope.files = element.files;
$scope.src = event.target.result
);
reader.readAsDataURL(element.files[0]);
]);
save_data.php
<?php
require "dbconnection.php";
$ext = pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
$image = time().'.'.$ext;
move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$image);
$query="insert into test_table values ('null','$image')";
mysqli_query($con,$query);
?>
【讨论】:
【参考方案27】:这行得通
文件.html
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "app">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
</body>
<script src="controller.js"></script>
</html>
controller.js
var app = angular.module('app', []);
app.service('fileUpload', ['$http', function ($http)
this.uploadFileToUrl = function(file, uploadUrl)
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd,
transformRequest: angular.identity,
headers: 'Content-Type': undefined
).success(function(res)
console.log(res);
).error(function(error)
console.log(error);
);
]);
app.controller('fileCtrl', ['$scope', 'fileUpload', function($scope, fileUpload)
$scope.uploadFile = function()
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload.php"; // upload url stands for api endpoint to handle upload to directory
fileUpload.uploadFileToUrl(file, uploadUrl);
;
]);
</script>
文件上传.php
<?php
$ext = pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
$image = time().'.'.$ext;
move_uploaded_file($_FILES["file"]["tmp_name"],__DIR__. ' \\'.$image);
?>
【讨论】:
【参考方案28】:上传文件
<input type="file" name="resume" onchange="angular.element(this).scope().uploadResume()" ng-model="fileupload" id="resume" />
$scope.uploadResume = function ()
var f = document.getElementById('resume').files[0];
$scope.selectedResumeName = f.name;
$scope.selectedResumeType = f.type;
r = new FileReader();
r.onloadend = function (e)
$scope.data = e.target.result;
r.readAsDataURL(f);
;
下载文件:
<a href="applicant.resume" download> download resume</a>
var app = angular.module("myApp", []);
app.config(['$compileProvider', function ($compileProvider)
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);
]);
【讨论】:
【参考方案29】:app.directive('ngUpload', function ()
return
restrict: 'A',
link: function (scope, element, attrs)
var options = ;
options.enableControls = attrs['uploadOptionsEnableControls'];
// get scope function to execute on successful form upload
if (attrs['ngUpload'])
element.attr("target", "upload_iframe");
element.attr("method", "post");
// Append a timestamp field to the url to prevent browser caching results
element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());
element.attr("enctype", "multipart/form-data");
element.attr("encoding", "multipart/form-data");
// Retrieve the callback function
var fn = attrs['ngUpload'].split('(')[0];
var callbackFn = scope.$eval(fn);
if (callbackFn == null || callbackFn == undefined || !angular.isFunction(callbackFn))
var message = "The expression on the ngUpload directive does not point to a valid function.";
// console.error(message);
throw message + "\n";
// Helper function to create new i frame for each form submission
var addNewDisposableIframe = function (submitControl)
// create a new iframe
var iframe = $("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px;
border: none; display: none' />");
// attach function to load event of the iframe
iframe.bind('load', function ()
// get content - requires jQuery
var content = iframe.contents().find('body').text();
// execute the upload response function in the active scope
scope.$apply(function () callbackFn(content, content !== "" /* upload completed */); );
// remove iframe
if (content != "") // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
setTimeout(function () iframe.remove(); , 250);
submitControl.attr('disabled', null);
submitControl.attr('title', 'Click to start upload.');
);
// add the new iframe to application
element.parent().append(iframe);
;
// 1) get the upload submit control(s) on the form (submitters must be decorated with the 'ng-upload-submit' class)
// 2) attach a handler to the controls' click event
$('.upload-submit', element).click(
function ()
addNewDisposableIframe($(this) /* pass the submit control */);
scope.$apply(function () callbackFn("Please wait...", false /* upload not completed */); );
var enabled = true;
if (options.enableControls === null || options.enableControls === undefined || options.enableControls.length >= 0)
// disable the submit control on click
$(this).attr('disabled', 'disabled');
enabled = false;
$(this).attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');
// submit the form
$(element).submit();
).attr('title', 'Click to start upload.');
else
alert("No callback function found on the ngUpload directive.");
;
);
<form class="form form-inline" name="uploadForm" id="uploadForm"
ng-upload="uploadForm12" action="rest/uploadHelpFile" method="post"
enctype="multipart/form-data" style="margin-top: 3px;margin-left:
6px"> <button type="submit" id="mbUploadBtn" class="upload-submit"
ng-hide="true"></button> </form>
@RequestMapping(value = "/uploadHelpFile", method =
RequestMethod.POST) public @ResponseBody String
uploadHelpFile(@RequestParam(value = "file") CommonsMultipartFile[]
file,@RequestParam(value = "fileName") String
fileName,@RequestParam(value = "helpFileType") String
helpFileType,@RequestParam(value = "helpFileName") String
helpFileName)
【讨论】:
请格式化您的答案,它的格式不正确以上是关于使用 AngularJS 上传文件的主要内容,如果未能解决你的问题,请参考以下文章
angularjs使用$http post上传文件的时候,怎样获取文件上传的进度
使用 AngularJS 和 SpringMVC 进行多部分文件上传