`

AngularJS与服务端协作及登录

阅读更多

        $http服务是AngularJS中的核心服务之一,我们可以扩展它,从而实现web应用中的各种常用需求,包括:

        1.带有一个通用的错误处理点

        2.处理授权和登录重定向

        3.与那些无法理解或者返回JSON的服务端交互

        4.通过JSONP与外部服务(指同一来源之外的)交互

        所以,在这个例子中,我们将会看到一个完整的应用骨架,它具有以下特点:

        1.在butterbar指令中显示所有不可恢复的错误(非401),如果存在错误,则将错误显示在所有页面上

        2.有一个ErrorService服务,它用来在指令、视图以及控制器之间进行交互

        3.每当服务器返回一个401响应时,就会触发一个事件(event:loginRequired)。这个事件会被根控制器处理,根控制器是负责监视并管理整个应用的

        4.处理发送给服务器的请求,对于当前特定的用户来说,这些请求需要带有一些授权头信息

        我们不分析整个应用(路由、模板等),因为大部分内容都相当简单,我们只重点关注那些重要的部分。

        我们首先来看一看Error服务:

var servicesModule = angular.module('myApp.services', []);

servicesModule.factory('ErrorService', function(){
	return {
		errorMessage: null,
		setError: function(msg) {
			this.errorMessage = msg;
		},
		clear: function() {
			this.errorMessage = null;
		}
	};
});

        error message指令是独立于Error服务的,它会查找alert message属性并绑定到此信息上。然后当alert message信息存在时,就显示自身。

//用法:<div alert-bar alertMessage="myMessageVar"></div>
angular.module('myApp.directives', []).
directive('alertBar', ['$parse', function($parse){
	return {
		restrict: 'A',
		template : '<div class="alert alert-error alert-bar"' + 
			'ng-show="errorMessage">' +
			'<button type="button" class="close" ng-click="hideAlert()">' + 
			'x</button>' + 
			'{{errorMessage}}</div>',
		link: function(scope, elem, attrs) {
			var alertMessageAttr = attrs['alertmessage'];
			scope.errorMessage = null;
			
			scope.$watch(alertMessageAttr, function(newVal){
				scope.errorMessage = newVal;
			});
			scope.hideAlert = function() {
				scope.errorMessage = null;
				//同时清除绑定变量上的错误信息。
				//这样做之后,当同样的错误再次出现时,alert bar会再次显示出来。
				$parse(alertMessageAttr).assign(scope, null);
			};
		}
	};
}]);

        然后我们把alert bar添加到HTML中,示例如下:

<div alert-bar alertmessage="errorService.errorMessage"></div>

        在添加以上HTML之前需要保证ErrorService被命名为"errorService"并存储在控制器的作用域中。也就是说,如果RootController是负责添加AlertBar的控制器,那么需要使用以下代码:

app.controller('RootController', ['$scope', 'ErrorService', function($scope, ErrorService) {
    $scope.errorService = ErrorService;
});

        如我在控制器中增加如下一行代码:

$scope.errorService.errorMessage = '请求服务失败!';

        运行结果:

 

        这样就给了我们一种非常优雅的显示和隐藏错误及警告信息的框架。现在,我们来看看如何通过一个拦截器来处理服务器扔给我们的各种状态码。

servicesModule.config(function($httpProvider) {
	$httpProvider.responseInterceptors.push('errorHttpInterceptor');
});

//把拦截器注册成一个服务,拦截所有Angular ajax HTTP调用
servicesModule.factory('errorHttpInterceptor', function($q, $location, ErrorService, $rootScope) {
	return function(promise) {
		return promise.then(function(response) {
			return response;
		}, function(response) {
			if(response.status === 401) {
				$rootScope.$broadcast('event:loginRequired');
			}else if(response.status >= 400 && response.status < 500) {
				ErrorService.setError('Server was unable to find' + 
					' what you were looking for... Sorry!!');
			}
			return $q.reject(response);
		});
	};
});

        现在唯一缺少的东西就是一些控制器,我们需要用它们来监听loginRequired事件,然后重定向到登录页(或者做一些更复杂的事情,例如显示一个带有登录选项的模态对话框)。

$scope.$on('event:loginRequired', function() {
	$location.path('/login');
});

        接下来的内容就是如何处理需要授权的请求了。举例来说,假设所有需要授权的请求都需要一个头信息“Authorization",它的值为当前登录的用户。由于这个值每次都会改变,所以我们不能使用默认的transformRequests函数,因为这些东西需要在配置层面上进行修改。作为替代 ,我们需要封装$http服务,利用它来创建我们自已的AuthHttp服务。

        我们还需要一个Authentication服务,用它来存储用户的授权信息(获取任何你所需要的信息,一般作为登录过程的一部分)。AuthHttp服务将会指向这个Authentication服务,然后添加必要的头信息来为请求授权。

//这个factory只会被执行一次,然后authHttp就会被存储下来。也就是说,后面对authHttp服务的请求将会返回同一个authHttp实例
servicesModule.factory('authHttp', function($http, Authentication) {
	var authHttp = {};
	
	//在请求上添加正确的头信息
	var extendHeaders = function(config) {
		config.headers = config.headers || {};
		config.headers['Authorization'] = Authentication.getTokenType() + '' + authentication.getAccessToken();
	};
	
	//针对每个$http调用都需要做以下事情
	angular.forEach(['get', 'delete', 'head', 'jsonp'], function(name) {
		authHttp[name] = function(url, config) {
			config = config || {};
			extendHeaders(config);
			return $http[name](url, config);
		};
	});
	
	angular.forEach(['post', 'put'], function(name) {
		authHttp[name] = function(url, data, config) {
			config = config || {};
			extendHeaders(config);
			return $http[name](url, data, config);
		};
	});
	
	return authHttp;
});

        所在需要授权的请求都是通过authHttp.get()( 而不是$http.get())发出的。一旦为Authentication服务设置了正确的信息之后,你的调用就可以轻松地发出去了。我们对Authentication也使用了一个服务,所以信息在整个应用中都是可用的,没有必要在每次路由发生变化时都重新获取。

 

资料来源:《用AngularJS开发下一代Web应用》

  • 大小: 11.7 KB
分享到:
评论

相关推荐

    ASP.NET MVC+Angularjs

    将AngularJS与ASP.NET MVC结合使用,可以实现前后端分离的开发模式,前端利用AngularJS处理用户交互和页面逻辑,后端ASP.NET MVC专注于API接口的提供和服务端的业务逻辑处理。这种模式有助于提高开发效率,减少重复...

    精通AngularJS part1

    不写代码时,Pawel 常在会议与活动上为AngularJS布道。 Peter Bacon Darwin已经积累了20年以上的编程经验,他在.NET发布之前,就已经用它工作了。他还对IronRuby的开发有所贡献。他曾在Avanade和IMGROUP做IT顾问。...

    AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录

    AngularJS、Node.js、MongoDB是当前流行的前端、后端以及数据库技术,三者结合可以构建出性能良好、易于维护的全栈应用程序。...项目全程在GitHub上开源,方便社区协作与贡献,为全栈开发实践者提供了很好的参考。

    视频服务端后台研发工程师职位描述与岗位职责任职要求.docx

    根据提供的文档内容,我们可以归纳出四个不同的职位描述与岗位职责及任职要求,下面将逐一解析。 ### 一、视频服务端后台研发工程师 **职位描述:** - 负责今日头条视频相关产品的后台业务研发。 - 负责在线大流量...

    shlink-web-client-angularjs:用于Shlink的AngularJS客户端应用程序

    "shlink-web-client-angularjs" 是一个基于 AngularJS 开发的Web客户端应用程序,专门设计用于与 Shlink 服务端交互。AngularJS 是一个强大的前端JavaScript框架,由Google维护,它使得构建动态单页应用(SPA)变得...

    PocoAngularTodo:POCO 和 AngularJs 的待办事项列表示例

    总结,"PocoAngularTodo"项目是一个融合了C++后端与AngularJS前端的Web应用示例,旨在展示如何用这两种技术协作创建一个功能完备的待办事项管理系统。开发者通过学习此项目,可以深入了解C++的POCO库和AngularJS框架...

    NotificationService:AngularJS 客户端 + SignalR Hub 提供实时通知

    通过其强大的MVVM(Model-View-ViewModel)设计模式,AngularJS能够自动同步数据模型与视图,从而在数据更新时实时反映到用户界面上,无需手动操作。 **SignalR** 是ASP.NET框架的一个扩展,专门用于实现实时双向...

    基于node最简单最小化的web服务器

    在前后端分离的场景下,AngularJS可以与Node.js web服务器配合,通过Ajax请求获取服务器数据,实现页面的动态更新。 在这个项目中,可能的实现步骤包括: 1. 安装Node.js环境。 2. 使用npm(Node.js的包管理器)...

    高级web前端开发工程师的主要职责模板(合集).docx

    8. **团队协作与技术分享**:组织和参与定期的学习分享,提升团队整体技术水平,共同探讨技术实现方案,进行应用及系统整合。 9. **技术选型与创新**:根据业务发展需求,进行前端技术选型,引领团队探索前端技术的...

    应用开发工程师(nodejs)职位描述与岗位职责任职要求.docx

    1. **协作完成相关功能及场景的应用开发、集成与验证**:这表明候选人需要具备良好的团队协作能力,能够与其他开发人员共同完成复杂的功能开发。 2. **负责Android中间层核心组件的定制和维护,并进行中间件模块的...

    trail:Trail 是一个协作的实时任务管理环境

    Trail 是一个协作的实时任务管理环境。 堆 Trail 的客户端使用 AngularJS 构建,使用 Firebase 作为持久性服务。 Trail 还使用 NodeJS 服务器来存储附加(外围)数据。 服务 Firebase:用于获得实时用户体验。 所有...

    基于HTML5的APP应用开发教学大纲-课程标准-最全最新.docx

    - **课程目标**:使学生能够独立完成静态网页与APP界面的设计与制作,掌握动态网页设计方法及APP与服务端的交互机制。 - **职业技能**:培养学生的Web前端开发设计能力,使其能够在工作中展现出色的操作技能、团队...

    web开发各种技术

    在Web开发领域,JavaWeb和Web开发是一片广阔的天地,涵盖了众多技术和工具,它们相互协作构建出复杂的互联网应用。本文将深入探讨这些技术,并逐一解析它们的重要性和应用场景。 首先,让我们从基础开始,Web开发的...

    web开发的页面框架

    后台模板可能是指用于处理业务逻辑和服务端数据的部分,而前台模板则涉及用户在浏览器中看到的实际界面。这种分离式的开发方式有助于保持代码的整洁和可维护性,同时也方便设计师和开发者协作。 例如,后台模板可能...

    大数据架构师岗位的基本职责.pdf

    2. 第三方接口集成与性能优化:他们负责调用和实现第三方API,以确保不同系统的无缝协作。同时,他们会持续改进服务性能和容量,保证在不同环境下的兼容性和执行效率。 3. 代码编写与维护:大数据架构师依据设计...

    Single-Page-App-Break, 单页应用开发权威指南.zip

    AngularJS、React、Vue.js等前端框架为构建SPA提供了强大的支持。 在SPA开发中,路由管理是一个关键组件。它负责处理URL与页面视图之间的映射,确保用户在导航时能够正确地展示和更新内容。例如,React Router和Vue...

    系统前后端平台开发分离实践.pdf

    1. **远古网页三剑客手工工作坊时代**:在这个阶段,开发者通常是全能的,他们负责与客户沟通需求,同时进行服务器优化。此时的前端主要是HTML(HTML 4)和简单的CSS,后端则负责业务逻辑和数据处理。由于前后端职责...

    通过MVC模式将Web视图和逻辑代码分离.doc

    总的来说,MVC模式提供了一种有效组织Web应用代码的方式,无论是服务端还是客户端,都能通过这种方式提高代码的可读性、可维护性和团队协作效率。在实际项目中,可以根据需求选择合适的框架,如AngularJS、React或...

Global site tag (gtag.js) - Google Analytics