AngularJS上传下载文件及$http总结

 

$http

只要涉及到与后台进行数据交互,我们可以使用内置的$http服务直接同外部进行通信。$http服务只是简单的封装了浏览器原生的XMLHttpRequest对象。

举个例子:

将$http当做函数来使用,这时需要传入一个设置对象,用来说明如何构造XHR对象。

$http({
method:'GET',
url:'/api/users.json',
params:{
'username':'wuliangchen'
});
 

其中设置对象可以包含以下主要的键:
①method
可以是:GET/DELETE/HEAD/JSONP/POST/PUT
②url:绝对的或者相对的请求目标
params(字符串map或者对象)
这个键的值是一个字符串map或对象,会被转换成查询字符串追加在URL后面。如果值不是字符串,会被JSON序列化。
比如这个:
//参数会转为?name=wlc的形式
$http({
params:{'name':'wlc'}
});

④data(字符串或者对象)
这个对象中包含了将会被当作消息体发送给服务器的数据。通常在发送POST请求时使用。

从AngularJS 1.3开始,它还可以在POST请求里发送二进制数据。要发送一个blob对象,你可以简单地通过使用data参数来传递它。
例如:
 

var blob=new Blob(['Hello world'],{type:'text/plain'});
$http({
method:'POST',
url:'/',
data:blob
});

 

后端接收不到AngularJS $http.POST异步后台无法获取请求参数解决方法:

Angular的默认请求头,

$httpProvider.defaults.headers.post: (header defaults for POST requests)

Content-Type: application/json

$httpProvider.defaults.headers.put(header defaults for PUT requests)

Content-Type: application/json

其中Angular的post和put都是application/json

AngularJS,传输数据使用Content-Type: application/json和{ "foo": "bar", "baz": "moe" }这样的json序列。

所以下把Content-Type设置成x-www-form-urlencodedand之后,还需要转换序列的格式.

$http({method: 'POST', url: 'agent/modifyagent',data: {
    'hostname': agent.host_name,
    'agentnat': agent.host_nat_ip,
    'agentip': agent.host_ip ,
    'proxyip': agent.proxy_ip,
    'isvaild': agent.is_valid,
    'desc': agent.description,
    'hostport': agent.host_port,
    'proxyport': agent.proxy_port

},
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' } ,
    transformRequest: function(obj) {
        var str = [];
        for (var p in obj) {
            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        }
        return str.join("&");
    } }).
    success(function () {
        console.log('修改后主机信息:'+JSON.stringify(agent));
        return logger.logSuccess('修改主机成功!');
    }).
    error(function () {
        console.log('修改后主机信息:'+JSON.stringify(agent));
        return logger.logError('修改主机出错!');
    });

 

 

简言之:

1.HTTP请求的content-Type字段指明了报文的数据格式,如Angular的POST的请求将数据封装成了json,而原生HTML的数据格式是x-www-form-urlencode

2、后台默认以x-www-form-urlencode的方式去解析POST的参数,所以后台解析不了Angular的请求。

 

 

上传Angularjs $http post file and form data

方法一:用原生FormData

对于前端上传,先来讲讲input。<input> 标签用于搜集用户信息。根据不同的 type 属性值,输入字段拥有很多种形式。输入字段可以是文本字段、复选框、掩码后的文本控件、单选按钮、按钮等等【button、checkbox、file、hidden、image、password、radio、reset、submit、text】。

 

<div layout layout-align="center center" class="input-container">
    <span class="input-title">PM和JSON文件至少传一个【按Ctrl可多选】:</span>
    <input id="fileId" type="file" ng-model="myFile" multiple="multiple" >
</div>

 

对于file、image这种上传,或者file、image和其他混合上传就不是很好处理。

场景:新用户注册,包括姓名、密码、照片等

在此介绍一个FormData对象,

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.

想要更详细的了解如何使用FormData对象, 请查看使用FormData对象.

$mdDialog.show({
    templateUrl: 'views/common/loading.html',
    parent: angular.element(document.body),
    clickOutsideToClose: false,
    onComplete: function () {
        $http({method: 'POST', url:'agent/uploadhandler', data: fd,
            headers: {'Content-Type':undefined},
            transformRequest: angular.identity }).
            success(function () {
                if($scope.hostcheckeds.length>1){
                    for(var i=1;$scope.hostcheckeds.length;i++){

                        $scope.uploadKeyAndIp($scope.hostcheckeds[i].agentip,key);

                    }

                }
                $mdDialog.hide();
                return logger.logSuccess('上传成功!');
            }).
            error(function () {
                $mdDialog.hide();
                return logger.logError('上传失败!');
            });

    }

}

其中fd

var fd = new FormData();

var files = document.querySelector('input[type=file]').files;(或者用$scope.myFile获取)

            if(files.length>=1){

                //往fd对象加入两个文件

                for(var i=0;i<files.length;i++){

                    if(files[i].name.match('.json')=='.json'){

                        fd.append('conf',files[i]);

                    }else{

                        fd.append('pm',files[i]);

                    }

                }

                //传带文件的ip

                fd.append('agentip', $scope.hostcheckeds[0].agentip);

 

以上要注意的是,因为是通过anjularjs的http请求来上传文件的,所以要让当前的request成为一个Multipart/form-data请求,anjularjs对于POST和GET请求默认的Content-Type header 是application/json。通过设置‘Content-Type’: undefined,这样浏览器不仅帮我们把Content-Type 设置为 multipart/form-data,还填充上当前的boundary,如果你手动设置为: ‘Content-Type’: multipart/form-data,后台会抛出异常:the current request boundary parameter is null。通过设置 transformRequest: angular.identity ,anjularjs transformRequest function 将序列化我们的formdata object. 

data: fd,不能像普通的参数一样写为:params:{ fd,…},具体的解释是: 
官方文档

params – {Object.<string|Object>} – Map of strings or objects which will be serialized with theparamSerializer and appended as GET parameters.

data – {string|Object} – Data to be sent as the request message data.

 

在GET方法中可以使用params ,在POST/PUT/PATCH/DELETE中不能使用params 来传递数据,要使用data来传递。

  • 如果需要实现同一个窗口能够多选文件,使用加上<input type="file" multiple="true" />即可。
  • 如果需要限制文件类型,可以使用<input type="file" accept="image/*" />'即可。

accept取值类型列表

后缀名       MIME名称

*.3gpp    audio/3gpp, video/3gpp

*.ac3    audio/ac3

*.asf       allpication/vnd.ms-asf

*.au           audio/basic

*.css           text/css

*.csv           text/csv

*.doc    application/msword   

*.dot    application/msword   

*.dtd    application/xml-dtd   

*.dwg    image/vnd.dwg   

*.dxf      image/vnd.dxf

*.gif            image/gif   

*.htm    text/html   

*.html    text/html   

*.jp2            image/jp2   

*.jpe       image/jpeg

*.jpeg    image/jpeg

*.jpg          image/jpeg   

*.js       text/javascript, application/javascript   

*.json    application/json   

*.mp2    audio/mpeg, video/mpeg   

*.mp3    audio/mpeg   

*.mp4    audio/mp4, video/mp4   

*.mpeg    video/mpeg   

*.mpg    video/mpeg   

*.mpp    application/vnd.ms-project   

*.ogg    application/ogg, audio/ogg   

*.pdf    application/pdf   

*.png    image/png   

*.pot    application/vnd.ms-powerpoint   

*.pps    application/vnd.ms-powerpoint   

*.ppt    application/vnd.ms-powerpoint   

*.rtf            application/rtf, text/rtf   

*.svf           image/vnd.svf   

*.tif         image/tiff   

*.tiff       image/tiff   

*.txt           text/plain   

*.wdb    application/vnd.ms-works   

*.wps    application/vnd.ms-works   

*.xhtml    application/xhtml+xml   

*.xlc      application/vnd.ms-excel   

*.xlm    application/vnd.ms-excel   

*.xls           application/vnd.ms-excel   

*.xlt      application/vnd.ms-excel   

*.xlw      application/vnd.ms-excel   

*.xml    text/xml, application/xml   

*.zip            aplication/zip   

*.xlsx     application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

 

方法二:插件

AngularJS 的文件上传控件有两个:
    angular-file-upload:https://github.com/nervgh/angular-file-upload
    ng-file-upload:https://github.com/danialfarid/ng-file-upload

  这两个非常类似,连js文件的结构都是一样的。核心的js是.min.js,还都有一个-shim.min.js,用来支持上传进度条和上传暂停等高级功能。

angular-file-upload 是一款轻量级的 AngularJS 文件上传工具,为不支持浏览器的 FileAPI polyfill 设计,使用 HTML5 直接进行文件上传。

特性

  支持上传进度,在上传的时候,可以取消或者中止,支持文件拖拽(HTML5),目录拖拽(weikit),CORS, PUT(html5)/POST 方法

  支持使用 Flash polyfill FileAPI  跨浏览器上传 (HTML5 和 non-HTML5) 。允许客户端在上传之前验证或者修改文件。

  当文件的内容类型使用 $upload.http()时,支持直接上传到 CouchDB,imgur 等等。支持 Angular http POST/PUT 请求的进度事件

  轻量级,使用常规的 $http 来上传(支持非 HTML5 浏览器),所以提供所有 Angular $http 功能。

下载

两种思路:

①设置下载为一个按钮,去后台请求,之后获取当前的URL,用window.open打开该URL。

var openDownloadUrl=window.location.origin+'/agent/downloadhandler?agentip='+agentip+'&handlername='+handlername;
window.open(openDownloadUrl);

 

②设置下载为一个超链接,点击带参数的超链接

location.href="//http://localhost:13700/agent/downloadhandler?agentip='+agentip+'&handlername='+handlername;

  1. // 带#号的url,看?号的url,见下面  
  2. url = http://qiaole.sinaapp.com?#name=cccccc  
  3.   
  4. $location.absUrl();  
  5. // http://qiaole.sinaapp.com?#name=cccccc  
  6.   
  7. $location.host();  
  8. // qiaole.sinaapp.com  
  9.   
  10. $location.port();  
  11. // 80  
  12.   
  13. $location.protocol();  
  14. // http  
  15.   
  16. $location.url();  
  17. // ?#name=cccccc  
  18.   
  19. // 获取url参数  
  20. $location.search().name;  
  21. // or  
  22. $location.search()['name'];  
  23.   
  24. // 注:如果是这样的地址:http://qiaole.sinaapp.com?name=cccccc  

 

转载于:https://my.oschina.net/u/3298482/blog/903847

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值