将表单数据和图像从 HTML 页面绑定到 Angular 控制器
Posted
技术标签:
【中文标题】将表单数据和图像从 HTML 页面绑定到 Angular 控制器【英文标题】:Binding form-data along with image from HTML page to Angular Controller 【发布时间】:2018-01-17 18:16:14 【问题描述】:我正在尝试将 html 页面中的 form-data 与图像 绑定到 Angular Controller,然后将 form-data 与图像数据一起附加,最后将数据 POST 到API。 所以我搜索并知道,遗憾的是 AngularJs 没有任何图像文件指令。 所以我得到的最终解决方案是创建一个自定义指令,将表单数据附加到图像,然后将该数据发布到服务器。 我尝试了什么: HTML
<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text" ng-model="UserName" required="required">
<input type="text" ng-model="FirstName" required="required">
<input type="file" ng-model="Image" required="required">
<button type="submit" ng-click="product()">save</button>
</form>
自定义指令:
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]);
);
);
;
]);
POST 方法:
scope.product = function()
var pro = $scope.pro;
console.log('Form Data : ' + pro);
var fd = new FormData();
angular.forEach($scope.Image, function(file)
fd.append('file', file);
);
fd.append('pro', JSON.stringify($scope.product));
$http.post('/products/createProduct', fd,
transformRequest: angular.identity,
headers:
'Content-type': undefined
)
.then(function(data)
$scope.ListProducts = data;
console.log($scope.ListProducts );
);
但问题是,控制器没有绑定任何东西,而且每次我的对象都是空的。 我什至尝试将数据记录到控制台,但没有得到任何内部数据。 我不知道我做错了什么。 请帮忙..
更新
我能够绑定数据,但是在发布图像路径和其他表单数据时,我得到了所有的空值。
angular.js:14642 可能未处理的拒绝:"data":null,"status":-1,"config":"method":"POST","transformRequest":[null]," transformResponse":[null],"jsonpCallbackParam":"callback","url":"/products/createProduct","data":"productStock":["price ":"","color":""],"productThumbnail":"0":,"headers":"Accept":"application/j儿子, text/plain, /","Content-Type":"application/json;charset=utf-8","statusText":"" 错误
【问题讨论】:
请记住,使用 FormData API 上传图像效率不高,因为 base64 encoding 会增加 33% 的额外开销。考虑直接上传文件并使用url parameters 获取更多数据。 @georgeawg:我该怎么做? -1 状态通常意味着CORS problem。浏览器阻止了 XHR,因为它违反了Same Origin Policy。 AngularJS No 'Access-Control-Allow-Origin' header 可能重复,How to enable CORS in AngularJs 可能重复,Angular HTTP: Status -1 and CORS 可能重复等 – georgeawg 5 小时前 【参考方案1】:我对您的代码进行了改进。基本上你使用的是 ng-model,而不是像你的指令所说的 file-model,如果只有一个文件,fd.append 文件也不需要迭代。检查代码和plnkr。
控制器
$scope.product = function()
var pro = $scope.pro;
var fd = new FormData();
fd.append('file', $scope.form.Image);
fd.append('pro', JSON.stringify($scope.form));
$http.post('/products/createProduct', fd,
transformRequest: angular.identity,
headers:
'Content-type': undefined
)
.then(function(data)
$scope.ListProducts = data;
console.log($scope.ListProducts );
);
;
HTML
<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text" ng-model="form.UserName" required="required">
<input type="text" ng-model="form.FirstName" required="required">
<input type="file" file-model="form.Image" required="required">
<button type="submit" ng-click="product()">save</button>
</form>
form.Image.name
PLNKR EXAMPLE
**更新**
在网络上可以看到这个。发送数据时。
【讨论】:
感谢您的回答。我能够绑定数据,但是在发布图像路径以及其他表单数据时,我得到了所有的空值。 在浏览器开发者控制台的网络选项卡中,您可以检查数据是否正在发送到 api,以及数据名称如何。 formdata sendint 必须将一个名称文件拆分为另一个 pro 如果 api 是 php $_FILE('file'); 刚刚我签入 network-tab ,我得到了空值。【参考方案2】:<input type=file>
元素默认情况下不适用于ng-model directive。它需要一个custom directive:
与ng-model
一起使用的“files-input”指令的工作演示
angular.module("app",[]);
angular.module("app").directive("filesInput", 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" files-input ng-model="fileArray" multiple>
<h2>Files</h2>
<div ng-repeat="file in fileArray">
file.name
</div>
</body>
感谢您的回答。我试过你的代码,得到:
angular.js:14642 可能未处理的拒绝:"data":null,"status":-1,"config":"method":"POST","transformRequest":[null]," transformResponse":[null],"jsonpCallbackParam":"callback","url":"/products/createProduct","data":"productStock":["price ":"","color":""],"productThumbnail":"0":,"headers":"Accept":"application/j儿子, text/plain, /","Content-Type":"application/json;charset=utf-8","statusText":"" 错误
根据我的经验,-1
状态最常见的原因是浏览器因违反 Same Origin Policy. 而阻止了响应
出于安全原因,浏览器会限制从脚本中发起的跨域 HTTP 请求。例如,XMLHttpRequest 和 Fetch 跟在 same-origin policy 后面。因此,使用 XMLHttpRequest 或 Fetch 的 Web 应用程序只能向自己的域发出 HTTP 请求。为了改进 Web 应用程序,开发人员要求浏览器供应商允许跨域请求。
跨域资源共享 (CORS) 机制为 Web 服务器提供跨域访问控制,从而实现安全的跨域数据传输。现代浏览器在 API 容器中使用 CORS(例如 XMLHttpRequest 或 Fetch)来降低跨域 HTTP 请求的风险。
见Use CORS to allow cross-origin access.
【讨论】:
感谢您的回答。我尝试了您的代码,得到 angular.js:14642 可能未处理的拒绝:"data":null,"status":-1,"config": "method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/products/createProduct","data":" productStock":["price":"","color":""],"productThumbnail":"0":,"headers":"Accept":"application/json, text /plain, /","Content-Type":"application/json;charset=utf-8","statusText":"" 错误 哦,好吧。如果我使用<input type="file" files-input ng-model="product.productThumbnail" multiple>
,那么只有我得到上述错误。但如果我使用<input type="file" files-input ng-model="fileArray" multiple>
,则没有错误,但该图像名称未存储在数据库。
我在 network-tab:productThumbnail: name: 0:
中得到这个值,你可以看到没有图像名称。以上是关于将表单数据和图像从 HTML 页面绑定到 Angular 控制器的主要内容,如果未能解决你的问题,请参考以下文章
如何在Python框架Flask中将图像文件从表单上传到数据库