在AngularJS中是如何实现异步请求的?(与服务器进行交互)

  在AngularJS中,与服务器交互的能力同样依赖于XMLHttpRequest对象实现。正如在JS中一样,AngularJS对XMLHttpRequest对象进行了封装,使得开发者能以更优雅的方式与服务器进行Ajax交互。

   $http是AngularJS内置的一个Ajax支持的服务。与该服务配套使用的,还有如下常用的服务。

  1. $httpParamSerializer:该服务用于将JS对象转换为查询字符串。

  2.$httpParamSerializerJQLike:该服务用于将JS对象转换为查询字符串。该服务与上一个服务的细微区别是,它转换为的查询字符串更符合jQuery风格。

  3.$xhrFactory:一般不直接使用该服务。当开发者对AngularJS创建的XMLHttpRequest对象的方式不满意时,开发者可替换或修改该服务,从而创建自己的XMLHttpRequest对象.(一般来说,开发者没必要替换或修改$xhrFactory服务。)

接下来我们通过一个例子来看一下上述的服务是如何运用的:

<body ng-app="httpExample" ng-strict-di>
<div ng-controller="fkCtrl">
输入用户名<input type="text" ng-model="user.name" /><br/>


输入密码:<input type="text" ng-model="user.pass" /><br/>
$httpParamSerializer:{{serializer1}}<br />
$httpParamSerializerJQLike:{{serializer2}}<br />
</div>
<script type="text/javascript">
var app=angular.module("httpExample",[])
    .controller("fkCtrl",['$scope','$httpParamSerializer','$httpParamSerializerJQLike',function($scope,$httpParamSerializer,$httpParamSerializerJQLike){
	$scope.user={pass:'123456',name:'yeeko'};
	$scope.serializer1=$httpParamSerializer($scope.user);
	$scope.serializer2=$httpParamSerializerJQLike($scope.user);
	}]);
</script>

</body>

$http服务调用它的构造器即可与服务器交互,调用构造器时只要传入一个JS对象指定与服务器交互的选项即可。该JS对象支持如下属性。(仅列举常用的)


method:该属性指定发送请求的方式,该属性支持GET,POST等请求。

url:该属性指定发送请求的URL地址。

data:该属性指定请求参数。

headers:该属性指定发送请求的请求头。该属性应该是一个JS对象,对象的属性名表示请求头的名,属性值表示请求头的值。



调用$http服务的构造器将会返回一个Promise对象(简单来说就是一个容器,里面保存着在某个未来才会结束的事件的结果,是异步编程的一种解决方案。)接下来程序可调用该对象的then()方法传入resolve、reject回调函数,这两个回调函数相当于Ajax的交互成功、失败的回调函数。两个回调函数都支持一个response参数。下面示例示范了如何使用$http服务与服务器进行交互。


<script type="text/javascript" src="angular-1.6.2.js">
</script>
<script type="text/javascript" src="angular-sanitize.min.js">
</script>
</head>


<body ng-app="ajaxModule">
<div ng-controller="fkCtrl">
<h3>请输入你的信息</h3>
<form id="userForm">
   用户名:<input type="text" name="user" ng-model="params.user" /><br />
   喜欢的图书:<select multiple="multiple" name="books" ng-model="params.books">
      <option value="java">疯狂java讲义</option>
	  <option value="javaee">轻量级Java EE企业实战</option>
	  <option value="ajax">疯狂前端开发讲义</option>
	  <option value="xml">疯狂XML讲义</option>
	 </select><br />
	 <input type="button" id="load" value="发送异步请求" ng-click="send();"/>
</form><hr />
<div ng-bind-html="show"></div>
</div>
<script type="text/javascript">
angular.module("ajaxModule",['ngSanitize'])
      .controller('fkCtrl',['$scope','$http','$httpParamSerializer',function($scope,$http,$httpParamSerializer){
	  $scope.send=function(){
	  $http({
	  method:"POST",
	  url:'pro',
	  data:&httpParamSerializer($scope.params),
	  headers:{
	  'Content-Type':'application/x-www-form-urlencoded'
	  }
	 }).then(function successCallback(response)
	 {
	 $scope.show="服务器响应状态为:"+response.status+"<br />"
	 +response.data;
	 },function errorCallback(response){
	 $scope.show='服务器响应异常';
	 });
	 };
	 
	 }]);
	 </script>
	 
</body>

接下来是需要搭建服务器以及编写服务器端的脚本,在这里我就不细说了。


$http服务还提供了如下快捷方法与服务器进行交互,这些方法都是对$http的简化。

1.$http.get(url,[config]):发送GET请求的快捷方法

2.$http.head(url,[config]):发送HEAD请求的快捷方法

3.$http.post(url,data,[config]):发送POST请求的快捷方法

4.$http.put(url,data,[config]):发送PUT请求的快捷方法

5.$http.head(url,[config]):发送HEAD请求的快捷方法

6.$http.delete(url,[config]):发送delete请求的快捷方法

7.$http.jsonp(url,[config]):发送JSONP请求的快捷方法

8.$http.patch(url,data,[config]):发送JSONP请求的快捷方法

在这些方法中都可指定一个config参数,该参数的作用和直接使用$http时传入的config参数的作用相同。

下面示范了使用快捷方法$http.post()发送POST请求:

<script type="text/javascript" src="angular-1.6.2.js">
</script>
<script type="text/javascript" src="angular-sanitize.min.js">
</script>
</head>


<body ng-app="ajaxModule">
<div ng-controller="fkCtrl">
<h3>请输入你的信息</h3>
<form id="userForm">
   用户名:<input type="text" name="user" ng-model="params.user" /><br />
   喜欢的图书:<select multiple="multiple" name="books" ng-model="params.books">
      <option value="java">疯狂java讲义</option>
	  <option value="javaee">轻量级Java EE企业实战</option>
	  <option value="ajax">疯狂前端开发讲义</option>
	  <option value="xml">疯狂XML讲义</option>
	 </select><br />
	 <input type="button" id="load" value="发送异步请求" ng-click="send();"/>
</form><hr />
<div ng-bind-html="show"></div>
</div>
<script type="text/javascript">
angular.module("ajaxModule",['ngSanitize'])
      .config(function($httpProvider){
	  $httpProvider.default.headers.post['Content-Type']='application/x-www-form-urlencoded';
	       })   //该例与前面介绍的使用$http与服务器进行交互的代码区别在于此,挂断代码为整个模块进行了配置,为所有的post请求增加了Content-Type请求头,经过这样设置后,AngularJS在提交Post请求时,总会将Content-Type请求头设为'application/x-www-form-urlencoded';这样就不需要每次提交POST请求时都通过config进行设置了。
      .controller('fkCtrl',['$scope','$http','$httpParamSerializer',function($scope,$http,$httpParamSerializer){
	  $scope.send=function(){
	  $http.post('pro',$httpParamSerializer($scope.params))
	 .then(function successCallback(response)
	 {
	 $scope.show="服务器响应状态为:"+response.status+"<br />"
	 +response.data;
	 },function errorCallback(response){
	 $scope.show='服务器响应异常';
	 });
	 };
	 
	 }]);
	 </script>
	 

</body>



使用$http上传文件:

使用$http上传文件有两个关键点:

1.将表单内的文件以二进制的方式提交,这一点可借助于FormData来实现,因此只要在使用$http提交请求时将FormData设为请求参数即可。

2.不能以application/x-www-form-urlencoded方式提交请求,要以multipart/form-data的方式提交请求。实际上提价请求时不能将Content-Type请求头设为multipart/form-data,而是应该将请求头设为undefined,让AngularJS根据请求参数自动添加Content-Type请求头。

下面的代码示范了如何利用$http处理文件上传。

<script type="text/javascript" src="angular-1.6.2.js">
</script>
<script type="text/javascript" src="angular-sanitize.min.js">
</script>
</head>




<body ng-app="ajaxModule">
<div ng-controller="fkCtrl">
<form id="bookForm">
  书名:<input type="text" name="name"/><p>
  价格:<input type="text" name="price"/><p>
  作者:<input type="text" name="author"/><p>
  出版时间:<input type="month" name="publishDate"/><p>
  图书封面:<input type="file" name="cover" accept="image/*"/><p>
  <button type="button" ng-click="send();">提交</button>
</form>
<progress id="prog" min="0" max="100" ng-show="prog<100" value='{{prog}}'></progress>
<div ng-bind-html="show"></div>
</div>
<script type="text/javascript">
angular.module("ajaxModule",['ngSanitize'])
   .controller("fkCtrl",['$scope','$http',function($scope,$http){
       $scope.prog=100;
	   $scope.send=function(){
	         var formData=new FormData(document.querySelector("#bookForm"));
			 $http({url:'second.jsp',data:formData,method:'POST',headers:{
			 'Content-Type':undefined},
			 uploadEventHandlers:{
			 progress:function(e){
			   $scope.$apply(function(){
			       $scope.prog=(e.loaded/e.total)*100;
				   })
				   }
				   }
				   ])
		     .then(function successCallback(response)
	        {
	         $scope.show="服务器响应状态为:"+response.status+"<br />"
	         +response.data;
	        },function errorCallback(response){
	        $scope.show='服务器响应异常';
	        });
	        };
	 
	        }]);
</script>

</body>


使用$resource服务:

AngularJS还提供了一个ngResource模块,该模块专门用于支持RESTful风格的服务交互。(关于RESTFUL风格:客户端和服务器之间的交互在请求之间是无状态的,无状态的请求可以由任何可用服务器回答,这十分适合云计算之类的环境,客户端可以缓存数据以改进性能)。

  由于ngResource模块并不是AngularJS的核心部分,而是一个可选的模块,因此如果需要使用该模块,则需要在页面上单独引用该模块的JS库。

 引入该模块之后,接下来即可使用$resource服务了。使用$resource服务大致可分为两步:

1.调用$resource(url,[paramDefaults],[actions],options)构造器创建一个对象。

程序并不直接使用$resource与服务器通信,$resource是一个创建资源对象的工厂,用来创建同服务器端交互的对象。

var CreditCard=$resource('/user/:userId/card/:cardId',{userId:123,cardId:'@id');

以上代码返回的CreditCard对象包含了同后端服务进行交互的方法,因此可将CreditCard对象理解成与RESTful服务通信的接口。

2.调用通信对象的get,save,query,remove,delete方法与服务器交互。eg:{‘get’:{method:'GET'}}

eg:

var CreditCard=$resource('/user/:userId/card/:cardId',{userId:123,cardId:'@id');
var card=CreditCard.get({cardId:20},function(){...});



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值