65.9K
CodeProject 正在变化。 阅读更多。
Home

Angular JS:与服务器通信基础

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (16投票s)

2014年4月1日

CPOL

5分钟阅读

viewsIcon

92335

downloadIcon

2048

本文介绍了使用 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 为 100employee 的详细信息。此调用不会等待服务器响应。当服务器响应在未来的某个时间点收到时,将根据服务器响应调用适当的 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、跨站点请求伪造、安全性、测试代码库的详细信息。

参考

  1. http://angularjs.org/
© . All rights reserved.