Angular JS:与服务器通信基础
本文介绍了使用 JavaScript 库 Angular 进行服务器端通信的基础知识
引言
Angular JS 已经成为一个非常流行的框架,因为它允许扩展 HTML 来创建模板,并在视图和模型之间实现双向绑定。实际应用除了模板化之外,还依赖后端服务器来执行核心业务逻辑。Angular 提供了丰富的内置服务器通信支持,它不仅提供了作为服务器通信构建块的低级机制,还提供了用于与 RESTful 服务通信的内置包装器。
在本技巧中,我们将重点介绍如何使用 Angular JS 与服务器通信。
背景
AJAX 是单页应用程序的核心。它支持在不刷新页面的情况下与后端服务器进行通信。这一单一功能彻底改变了 Web 应用程序的开发方式。典型的 Web 应用程序现在侧重于分别获取数据和布局(HTML)。这与 ASP/JSP 应用程序的开发方式不同,在 ASP/JSP 应用程序中,数据和布局在服务器端合并以生成 HTML,然后流式传输到浏览器。由于 AngularJS 应用程序也是单页应用程序,因此它提供了丰富的内置 AJAX 通信支持。
让我们深入了解 Angular 为服务器端通信提供的支持的详细信息。
使用 $http 进行通信
在 Angular 中,与服务器通信的基本构建块是 $http
服务。$http
服务是核心 Angular 服务,它通过浏览器的 XMLHttpRequest
对象或 JSONP 来促进与远程 HTTP 服务器的通信。
此服务提供基本功能,例如
GET
POST
HEAD
删除
PUT
JSONP
Angular API 使用基于 Promise
接口的方法进行服务器端通信。这确保所有与服务器相关的调用都是非阻塞/异步调用,这意味着服务器的响应将在未来的某个时间点返回。Promise
接口确保响应将在到达时得到相应处理。有两种方法名称:success
和 error
用于处理来自服务器的响应。
$http.get("empMgr", {params: {op: 'get'}})
.success(function(data, status, headers, config) {
$scope.employee = data; // Sets the employee object in $scope
})
.error(function(data, status, headers, config) {
alert("failure");
});
};
在上面的示例中,会发出一个 AJAX GET
请求来查找 ID 为 100
的 employee
的详细信息。此调用不会等待服务器响应。当服务器响应在未来的某个时间点收到时,将根据服务器响应调用适当的 success
或 error
函数。
$http.post
如果我们需要使用 POST
方法将数据提交到服务器,我们可以使用 $http.post
API。以下是将数据发布到服务器的示例。
var dataToPost = {firstName: "Allen", lastName: "John"}; /* PostData*/
var queryParams = {params: {op: 'saveEmployee'}};/* Query Parameters*/
$http.post("empMgr" /* URL */, dataToPost, queryParams)
.success(function(serverResponse, status, headers, config) {
// Updating the $scope postresponse variable to update theview
$scope.postresponse = serverResponse.data.firstName + " " + serverResponse.data.lastName;
}).error(function(serverResponse, status, headers, config) {
alert("failure");
}
);
上面的示例将员工数据 POST 到服务器。此调用也是异步的。当服务器完成处理保存请求后,响应会返回,并调用相关的 success
/error
方法。
在 Angular 中处理 POST
请注意,Angular 的 $http.post
与 jQuery.post
不同。Angular 以 JSON 格式将数据发布到 HTTP 正文中,并将 content-type
设置为 application/json
,而 jQuery 发布的值的 content-type 为 'application/x-www-form-urlencoded;charset=utf-8
',因此我们需要在服务器端编写一些代码来解析 HTTP 正文以获取请求正文,或者我们需要配置 Angular 代码库以将请求作为键值对发送。
配置 $http 服务请求
虽然 $http.get,$http.post
等的默认实现足以满足大多数目的,但可能存在一些特定用例,我们需要自定义默认 API。例如,我们可能需要设置一些自定义标头、转换请求和响应、设置自定义超时、启用/禁用缓存以及设置响应类型。
$http
服务提供了一种内置机制,可以通过“config
”对象来自定义 HTTP 请求。$http.X
的所有 API 都将最后一个参数作为 config
对象来定制请求。
例如,我们可以使用 config
对象的 header
属性为 GET 请求设置 HTTP 标头中的授权令牌。
$http.get("empMgr",
{
params: {op: 'get'},
headers: {"AUTH_TOKEN": "1234567890"} // Custom headers put in.
})
.success(function(data, status, headers, config) {
$scope.employee = data; // Sets the employee object in $scope
})
.error(function(data, status, headers, config) {
alert("failure");
});
};
});
$http
服务也可以仅通过传递 config
对象来调用。config
对象支持以下属性
The supported options are :
$http({
method: string, // GET, POST, PUT, HEAD etc
url: string, // URL of resource being requested
params: object, // Query parameters, if not string goes as JSON string
data: string or object, // Data to be sent as request message data
headers: object, // Map representing the HTTP header
transformRequest: function transform(data, headersGetter) or an array of functions, // Transforms request
transformResponse: function transform(data, headersGetter) or an array of functions, // Transforms response
cache: boolean or Cache object, // Boolean to turn cache on or off
timeout: number, // Timeout to wait for response from server
withCredentials: boolean
});
与 RESTful 服务通信
如前所述,$http
是用于服务器端通信的低级 API,用于与服务器通信。在实际应用中,我们必须处理代表软件生态系统中实体的对象数据。在正常情况下,我们需要使用 $http
服务为这些对象的常见功能(如创建、读取、更新、删除)编写代码。
myAppModule.factory('EmployeeService', ['$http', function($http) {
var url = 'rest/employee';
return {
get: function(empID) {
return $http.get(url + '/' + empId);
},
save: function(employeeObj) {
var url = employeeObj.id ? url + '/' + employeeObj.id : url;
return $http.post(url, employeeObj);
},
query: function(empID) {
return $http.get(url + '/' + empID.id + '/reportees');
},
calculateSalary: function(employee) {
return $http.post(url + '/' + employee.id, employee, {params: {admin: true}});
}};
}
]);
为了解决这些重复的任务,Angular 提供了内置支持,可以使用 $resource
对象创建服务。该对象提供了常见功能,例如
Get
保存
查询
移除
删除
开箱即用,无需编写一行代码。它还提供了在服务中创建新方法的功能。以下代码片段解释了这个概念
// Service to fetch EmployeeListService
angularModule.factory("EmployeeListService", ['$resource', function($resource){
return $resource('rest/employee/:empId',
{empId: '@id'},
{calculateSalary: {method: 'POST', params: {charge: true}, isArray: false}});
}]) ;
现在,EmployeeListService
开箱即用地具有以下方法,无需编写一行代码Service
EmployeeListService.get()
EmployeeListService.save
EmployeeListService.save
EmployeeListService.query()
EmployeeListService.remove()
EmployeeListService.delete()
自定义方法
除了上述方法之外,$resource
服务还为我们提供了创建新方法的功能。这有助于我们执行自定义的 RESTful 服务器调用。以下示例显示了如何在 $resource
服务中定义自定义方法
// Service to fetch Reportees
angularModule.factory("EmployeeReporteeService", ['$resource', function($resource){
return $resource('rest/employee/:empId/reportees',
{empId: '@id'},
/**
* Custom method to find contact numbers.
*
* Method type is GET
* Additional Query parameter admin=true is sent
* The expected return type is an Array
*/
{contactNumbers: {method: 'GET', params: {admin: true}, isArray: true}});
}]);
如何使用 Include $resource 对象?
让我们看看如何在代码库中包含此 $resource
服务
//Step 1 : $resource is an optional module in Angular defined in a separate file,
//so we have to include its JS file in our HTML file.
<script src=” angular-resource.js”></script>
// Step 2: Include ngResource dependency in the module where we want to use it. This code will be controller.js
angular.module(‘samplemodule’, [‘ngResource’]);
// Step 3: Then inject the $resource in the service where you want to use it.
myAppModule.factory('EmployeeService', ['$resource', function($resource) {
$resource
服务接受 1 个必需参数和 2 个可选参数
- URL;必需:资源所在的 URL
- 查询参数:要与 URL 附加功能一起传递的参数:我们想要添加到服务中的其他方法。
源代码
附带的代码库是一个基于 Maven 的项目,在 Netbeans IDE 中创建。在服务器端,它使用 Java Servlet 来处理 $http.get
和 $http.post
。对于 RESTful 服务的创建,它使用 Jersey 1.8。它还使用 GSON 库将 List/Employee
对象转换为 JSON。

摘要
在本文中,我们仅讨论了 AngularJS 与服务器通信的基础知识。在下一篇文章中,我们将重点介绍 $q、跨站点请求伪造、安全性、测试代码库的详细信息。