XIANFESchool / FE-problem-collection

前端问题收集和知识经验总结
https://github.com/ShuyunXIANFESchool/FE-problem-collection/issues
63 stars 22 forks source link

如何使用angular上传文件 #22

Open Y-Phoenix opened 8 years ago

Y-Phoenix commented 8 years ago

1.首先添加html代码

<input type="file"  file-up-load="vm.fileUpLoad" />

2.接下来需要监听该控件的change事件,第一时间想到的肯定是
ng-change事件,但是实验会发现当选择要上传的文件后,是不会触发 该事件的,所以需要换一种方式解决这个问题,这里选择用指令的方式监听 onchange事件,从而触发对应的方法。

angular
    .module('fileUpLoadModule',[])
    .directive('fileUpLoad', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {             
                   var onChangeHandler = scope.$eval(attrs.fileUpLoad);
                   element.bind('change', onChangeHandler);
             }
        };
    });

3.在controller里写响应的处理函数,处理文件的上传逻辑

vm.fileUpLoad = function(event) {
    var file = event.target.files[0];
    var formData = new  FormData();
    formData.append('fileParam', file);
};

首先通过event获取file对象,然后将file添加到FormData中,以便于向后台传送

4.通过$resource请求将文件信息发送给后台,但是需要注意的是,因为传输的是文件,而$resource的post请求默认添加application/json作为Content-Type,所以需要改变其Content-Type值,通过参考angular官方文档,修改方式如下:

$resource('http://example.com', null, {
    upLoadFile: {
        method: 'POST',
        headers: {'Content-Type': undefined} 
       // $http默认会为post请求的Content-type设置为application/json,
       // 可以通过将它设置成undefined去删除默认设置的Content-type
    }
});

5.可以使用express mock上传请求,可以使用中间件connect-multiparty

参考文档:

  1. $http
  2. $resource
silence717 commented 8 years ago

上传文件的过程中,遇到同一个文件二次上传无效的问题。

不要采用删除当前input[type=file]这个节点,然后再重新创建dom这种方案,这样是不合理的。 解释如下: input[type=file]使用的是onchange去做,onchange监听的为input的value值,只有再内容发生改变的时候去触发,而value在上传文件的时候保存的是文件的内容,你只需要在上传成功的回调里面,将当前input的value值置空即可。 event.target.value='';

milo-wjh commented 8 years ago

new FormData 不兼容IE9 怎么处理? 使用value 后台接收不到。

hjzheng commented 8 years ago

@milo-wjh 使用其他方式吧!http://www.ruanyifeng.com/blog/2012/08/file_upload.html

当然简单的方法,使用现成的库 https://github.com/danialfarid/ng-file-upload