Angular中$http解析、简单封装手札

$http服务

1、$http 是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。

2、angular内置的$http服务简单的封装了浏览器原生的XMLHttpRequest对象,可以直接同外部进行通信。

3、$http服务只能接受一个参数,且该参数是一个对象,这个对象主要包含一些http请求的配置内容。如下:

var req = {
    method: 'POST',
    url: 'http://xxx.com',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: { test: 'test' }
}
//以下写法在angular1.5+已废弃
$http(req).success(function(data,header,config,status){
    //响应成功
    
}).error(function(data,header,config,status){
    //处理响应失败
});
//以下写法在angular1.5+支持
$http(req).then(
	function successCallback(res){
		 //响应成功
	},function errorCallback(res){
		//处理响应失败
	}
)

可以看到$http()方法返回的是一个promise对象,angular1.5+版本只支持响应返回时用then回调。但是用then回调会得到一个特殊的参数,代表了相应对象的成功或失败信息,还可以接受两个可选的函数作为参数。如:

$http(req).then(function(resp){
    //resp是一个响应对象

},function(resp){
    //带有错误信息的resp

});

then()方法回调和success(),error()回调的区别是,then()会接收到完整的对象,而success()和error()会对响应进行解构。

then()函数接收的response(响应对象)包含5个属性:

1、data(字符串或对象):响应体,就是后台返回的数据
2、status:相应http的状态码,如200
3、headers(函数):头信息的getter函数,可以接受一个参数,用来获取对应名字的值
4、config(对象):生成原始请求的完整设置对象
5、statusText:相应的http状态文本,如"ok"
6、xhrStatus: “complete”

常见$http的GET和POST传参问题:

一、GET,get比较简单,用惯ajax的同学都知道get一般通过url中拼接字符串进行请求,而在angular中get请求地址和参数分开,如下:

var req = {
	method: 'GET',
	url: 'http://xxx.com',
	header: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	params: {
		'id': id,
		'code': xcode
	}
}
$http(req).then(function successCallback(res){
		//success
	},function errorCallback(res){
		//faild
})

二、POST
1、不能直接使用params,例如:

var req = {
	method: 'POST',
	url: 'http://xxx.com',
	header: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	params: {
		'name': 'jack',
		'id': '12'
	}
}
$http(req).then(function successCallback(res){
		//success
	},function errorCallback(res){
		//faild
})

当你这样写的时候它会把id写到url后面就会出现:

http://xxx.com?name=jack&id=12

会在url后面添加"?name=jack"等等,因为params这个参数是用在GET请求中的,而POST/PUT/PATCH就需要使用data来传递;

扫描二维码关注公众号,回复: 8552901 查看本文章

2、直接使用data

var req = {
	method: 'POST',
	url: 'http://xxx.com',
	data: {
		'name': 'jack',
		'id': '12'
	}
}
$http(req).then(function successCallback(res){
		//success
	},function errorCallback(res){
		//faild
})

这样的话传递的,是存在于Request Payload中,后端无法获取到参数(可在network中查看)
这时发现Content-Type:application/json;charset=UTF-8,而POST表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,所以需要把Content-Type修改下!

3、修改一下Content-Type

var req = {
	method: 'POST',
	url: 'http://xxx.com',
	header: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	data: {
		'name': 'jack',
		'id': '12'
	}
}
$http(req)...//同上

这个时候数据仍然没有传递到后台去,虽然数据是放到了Form Data中但是发现是以对象的形式存在,所以需要进行序列化!

4、对参数进行序列化,通过属性transformRequest完成:

var req = {
	method: 'POST',
	url: 'http://xxx.com',
	header: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	transformRequest: function(obj) {  
		var str = [];  
		for (var s in obj) {  
			str.push(encodeURIComponent(s) + "=" + encodeURIComponent(obj[s]));  
		}  
		return str.join("&");  
	}  
	data: {
		'name': 'jack',
		'id': '12'
	}
}
$http(req)...//同上

自此完成post传参。

$http封装

1、$http的普通使用
$http({
    method: "GET",
    url: url,
    headers: {
    },
    timeout: 10000
}).then(successCallBack,errorCallBack);

这样的使用方式的问题在哪?
第一:如果一个项目的接口有100个,那这样的引用方式会引起大量的冗余代码。
第二:Api不够简洁,无法提供一个忽视底层实现的方式进行服务请求。比如,上传文件的时候要对headers进行额外的设置等。
第三:最重要的是,毫无技术积累(逼格不够高),下次同样的项目,你的代码还是无法复用,还是需要一遍遍的写$http。
so,我们要对 $http 进行封装,形成简洁易用、结构清晰的数据请求 Api。

2、angular服务封装的目标和实现思路。

目标:封装成向顶层提供get、post两种方式的Api,Api的参数配置只和url、data相关。形成类似于 RequestService.get(url,data).then 这样的Api。

封装思路:由于angular的$http本身就是基于Promise的,所以本身不用引入第三方promise库。只需要把相同的部分提取出来即可。当然,angular在这方面还提供了全局的拦截器服务。

3、封装

第一步、定义一个基于服务module模块。

//BaseService.module.js
(function(){
    "use strict";
    angular.module('BaseService',[]);
})();

第二步、拦截器实现

//BaseService.intercepter.js
(function(){
    "use strict";
    angular.module('BaseService')
    .factory('requestInterceptor', function ($rootScope, $log){
        return{
            request:function(config){
                return config;
            },
            requestError:function(config){
                return config;
            },
            response:function(res){
                //res返回不正常的处理
                return res;
            },
            responseError:function(res){
                //res返回错误处理
            }
        }
    }).config(function($httpProvider){
        $httpProvider.interceptors.push('requestInterceptor');
    })
})();

第三步、公共提取

//BaseService.comm.js
(function(){
    'use strict';
    angular.module('BaseService')
    .config(function(){
$httpProvider.defaults.useXDomain = true;   // 发送CORS


$httpProvider.defaults.withCredentials = false;  // 请求携带Cookies
            delete $httpProvider.defaults.headers.common['X-Requested-With'];
    })
    .provider("RequestService",function(){
        return {
            $get: function(){
                return {
                    get:function(url,data,processor){
                        //coding
                    },
                    post:function(url,data){ 
                        //coding
                    },
                    request: request
                }
            }
        }
    })
})()

ps:以上是对angular中$http服务的使用笔记。

发布了23 篇原创文章 · 获赞 10 · 访问量 416

猜你喜欢

转载自blog.csdn.net/qq_35593965/article/details/103179873