问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

angularjs上传文件怎么设置$http为multipart/form-data

发布网友 发布时间:2022-05-02 02:45

我来回答

2个回答

懂视网 时间:2022-05-12 05:06

本文给大家分享在使用angular上传图片的功能,在开发过程中遇到很多问题,最终都解决了,今天小编给大家介绍下Angular下H5上传图片的方法(可多张上传),非常不错,需要的朋友参考下

最近做的项目中用到了angular下上传图片功能,在做的过程中遇到了许多问题,最终都得以解决

angular上传时和普通上传时过程差不多,只不过是要不一些东西转化为angular的东西。

1.ng-file-select,指令angular是没此功能的,其实也是转化成了change事件,不多说,直接上代码

angular.module('myApp')
.directive('ngFileSelect', [ '$parse', '$timeout', function($parse, $timeout) {
 return function(scope, elem, attr) {
 var fn = $parse(attr['ngFileSelect']);
 elem.bind('change', function(evt) {
 var files = [], fileList, i;
 fileList = evt.target.files;
 if (fileList != null) {
  for (i = 0; i < fileList.length; i++) {
  files.push(fileList.item(i));
  }
 }
 $timeout(function() {
  fn(scope, {
  $files : files,
  $event : evt
  });
 });
 });
 };
 }])

2.服务 上传文件前预览并压缩图片功能

//上传文件预览
angular.module('myServers',[])
 .factory('fileReader', ['$q', '$log', function($q, $log) {
 var dataURItoBlob = function(dataURI) { 
 // convert base64/URLEncoded data component to raw binary data held in a string 
 var byteString; 
 if (dataURI.split(',')[0].indexOf('base64') >= 0) 
 byteString = atob(dataURI.split(',')[1]); 
 else 
 byteString = unescape(dataURI.split(',')[1]); 
 // separate out the mime component 
 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 
 // write the bytes of the string to a typed array 
 var ia = new Uint8Array(byteString.length); 
 for (var i = 0; i < byteString.length; i++) { 
 ia[i] = byteString.charCodeAt(i); 
 } 
 return new Blob([ia], { 
 type: mimeString 
 }); 
 }; 
 var onLoad = function(reader, deferred, scope,file) {
 return function() {
 scope.$apply(function() {
  var img = new Image();
  //前端压缩图片
  img.onload = function(){ 
  //resize the image using canvas 
  var canvas = document.createElement("canvas"); 
  var ctx = canvas.getContext("2d"); 
  var width = img.width; 
  var height = img.height; 
  var MAX_WIDTH = width>2500 ? width/2 : 2500; 
  var MAX_HEIGHT = height>2500 ? height/2 : 2500;
  if (width > height) { 
  if (width > MAX_WIDTH) { 
  height *= MAX_WIDTH / width; 
  width = MAX_WIDTH; 
  } 
  } else { 
  if (height > MAX_HEIGHT) { 
  width *= MAX_HEIGHT / height; 
  height = MAX_HEIGHT; 
  } 
  }
  canvas.width = width ; 
  canvas.height = height; 
  ctx.drawImage(img, 0, 0, width, height); 
  var dataURL = canvas.toDataURL('image/jpeg', 1);
  var blob = dataURItoBlob(dataURL); 
  if(blob.size > 2000 * 1024){
  dataURL = canvas.toDataURL('image/jpeg', .2);
  }else if(blob.size > 1000 * 1024){
  dataURL = canvas.toDataURL('image/jpeg', .5);
  }else{
  dataURL = canvas.toDataURL('image/jpeg', .8);
  }
  blob = dataURItoBlob(dataURL);
  deferred.resolve(blob);
  }
  img.src = URL.createObjectURL(file);
 });
 };
 };
 var onError = function(reader, deferred, scope) {
 return function() {
 scope.$apply(function() {
  deferred.reject(reader.result);
 });
 };
 };
 var onProgress = function(reader, scope) {
 return function(event) {
 scope.$broadcast("fileProgress", {
  total: event.total,
  loaded: event.loaded
 });
 };
 };
 var getReader = function(deferred, scope, file) {
 var reader = new FileReader();
 reader.onload = onLoad(reader, deferred, scope,file);
 reader.onerror = onError(reader, deferred, scope);
 reader.onprogress = onProgress(reader, scope);
 return reader;
 };
 var readAsDataURL = function(file, scope) {
 var deferred = $q.defer();
 var reader = getReader(deferred, scope,file);
 reader.readAsDataURL(file);
 return deferred.promise;
 };
 return {
 readAsDataUrl: readAsDataURL
 };
 }]);


这里说明一下,部分代码是参考别人的代码(http://blog.csdn.net/zx007fack/article/details/41073601),但是对其中内容做了修改,因为用原来的代码,如果不加前端压缩功能是正常的,前端压缩的话因为要用到canvas, 直接用reader.result在ios上图片的宽高拿到的直接是0,android上是可以的,具体原因不是很确定是不是base64的问题,所以我又直接把file传了进来,然后用原生js的方法新建图片元素拿到宽高,再用Canvas进行压缩,最后转成blob,通过formData传给后台。

3.controller代码

//选择图片后执行的方法
 $scope.fileArr = [];
 $scope.imgSrcArr = [];var i = 0; //为ios上图片都为image时添加序号
 $rootScope.onFileSelect = function(files, event) {
 //预览上传图片开始
 $rootScope.startLoading();
 var $this = angular.element(event.target);
 angular.forEach(files, function(value, index) {
 var fileIn = value;
 var fileInName = fileIn.name;
 var fileType = fileInName.substring(fileInName.lastIndexOf(".") + 1, fileInName.length);
 //解决ios下所有图片都为image.jpg的bug
 if(fileIn) {
  fileInName = fileInName.split('.')[0] + i + '.' + fileType;
  i++;
 }
 attachvo.push({
  name: fileInName,
  type: fileType
 });
 fileReader.readAsDataUrl(fileIn, $scope)
  .then(function(result) {
  result.name = fileInName;
  $scope.fileArr.push(result);
  $scope.imgSrcArr.push(URL.createObjectURL(result));
              //每次上传后清空file框,确保每次都能调用change事件
  document.querySelector('.upload').reset();
  });
 $scope.$on('fileProgress', function(event, data) {
  if(data.total == data.loaded) {
  $timeout(function() {
  //上传图片结束
  $rootScope.endLoading();
  }, 200)
  }
 }); 
 });
 $rootScope.showAttachment = false;
 };return false;
 }

这里处理了下图片,在名字上加了序号,因为在ios上每次选择的图片名字都叫image,查找了很多资料,说是safari的bug,后面版本才会解决,暂时只能以这种方式解决了。循环是上传多张图片

3.html代码

<ul class="upload-view-ul">
 <li ng-repeat="src in imgSrcArr" class="pull-left" ng-click="delCurUpload(src)" 
 ng-class="{'row-last': (($index+1) % 5==0)}">
 <span>x</span>
 <em ng-if='nrc'>{{formData.attachvo[$index].attachmentType}}</em>
 <img ng-src="{{src}}">
 </li>
 <p class="attachment" pop-type-select ng-if="nrc">+</p>
 <p class="attachment" ng-if="!nrc">
 +
 <form class="upload">
 <input type="file" name="file[]" ng-file-select="onFileSelect($files, $event)" multiple>
 </form>
 </p>
 </ul>

4.顺便把formdata时代码贴一下,采用H5上传图片的方式

this.FormdataPost = function(pathUrl, formId, formData, files) {
 var fd = new FormData();
 fd.append('formId', formId);
 if(files && angular.isArray(files)) {
 files.forEach(function(item) {
 fd.append('file', item, item.name);
 });
 }
 fd.append('formData', angular.toJson(formData, true));
 var httpConfig = {
 headers: {
 'Authorization': 'Bearer ' + this.token,
 'Content-Type': undefined
 },
 transformRequest: angular.identity
 };
 return $http.post(rootUrl + pathUrl, fd, httpConfig).then(function(data) {
 return data;
 }).catch(function(error) {
 $rootScope.interfaceName = pathUrl;
 $rootScope.setNewWortStatus({
 status: error.status,
 errInfo: error.data && error.data.statusInfo || ''
 });
 return error;
 });
 }

思路有一点混乱,不知道讲清楚了没有,想起来再添加吧

热心网友 时间:2022-05-12 02:14

前言:很久没更新博客,最近公司pc端技术选型用angular,这几天就赶鸭子上架,硬着头皮直接上手angular。其中有许多小坑陆陆续续踩起走。今天就遇到一个比较常见的问题:图片上传。 主题:图片上传服务器,然后通过服务器传阿里云。 不废话了直接贴前端代码: $http({   method: ‘POST‘,   url: ‘/wechatapp/User/setAvatar‘, data: data, headers: { ‘Content-Type‘: undefined }, transformRequest: function(data) { var formData = new FormData(); formData.append(‘avatar_data‘, data.adata); formData.append(‘avatar_file‘, data.file); return formData; }, data: { adata: scope.avatar_data, file: scope.avatar_file } }).success(function(d) { //请求成功 cb(d); }).error(function(err, status) { console.log(err); cb(err); }); 其实没神马难点,主要是取消post默认的Content-Type,然后已FormData的方式上传。一般ajax上传文件都是以FormData方式传。 以上就是本文给大家介绍Angular Js文件上传之form-data,希望大家喜欢。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 皮肤上有个红色的斑点 皮肤被出现红色斑 皮肤出现红色的斑点是怎么回事? 皮肤上起红色的斑点是怎么的,不痛也不痒而 皮肤出现红色斑点 视频号不能说的词汇涉及到知识产权吗? 一早起床发现皮肤出现大块红色斑点,是怎么回事? 御龙在天装备处理 初戴隐形眼镜者怎样才能更熟练掌握它的技巧??? 幼儿园开学后怎样做好未返园幼儿人员的追踪报告制度? 御龙在天装备怎么搞 孩子过于自卑怎么办? 御龙在天包裹满了 怎么清理。 怎么清理绑定的装备。 御龙在天里面的装备怎么修护 御龙在天绿装怎么处理 学拉面要多少钱? 身份证能取消补办吗 御龙在天手游战力怎么提高 御龙在天装备攻略 遗失的身份证找到了,能取消补办吗 angularjs怎么通过ajax上传文件 适合大学生创业项目推荐 AngularJS中文社区angular 怎么上传文件 angularjs使用$http post上传文件的时候,怎样获取文件上传的进度 angularjs 上传文件java 怎么接收 大学生创业有好项目推荐吗? angularjs里数组怎么引入工程文件夹里的图片 angularJS 如何绑定图片? 是否已经有了AngularJS的画布绘图指令 angularJS前端显示文件名是特定字符开头的多张图片 如何在angularjs NG angularjs 怎么把数据绑定到img中 海尔电热水器FCD-HM60GⅠ(E),请问这个热水器整天24小时的耗电量是多少度? 干海带发霉了还能吃吗 干海带长白霉了还能吃吗 城乡居民医保云南省省内异地大病报销比例 云南的医保卡在四川成都住院的报消多少 云南医保跨省报销比例 四川医保在云南能报百分之多少 云南医保卡在异地能用了,回去报销比例是多少我的医保是云南的,但我在异地广西玉林就的医,费用9000_百度问一问