AngularJS AJAX

时间:2020-01-09 10:34:01  来源:igfitidea点击:

AngularJS AJAX简介

在AngularJS中,我们可以通过几种不同的方式发送AJAX请求。这些是:

  • AJAX通过$ http服务进行调用。
  • 通过$ http服务进行JSONP调用。
  • REST类型的调用。

注意:到目前为止,仅涵盖了$ http服务(普通的AJAX和JSONP),但这足以使我们开始在AngularJS中使用AJAX。开始使用AJAX不需要理解REST API(就我个人而言,我并不那么喜欢它,我们可以使用$ http服务一样轻松地完成此操作)。

$ http服务

$ http服务是将AJAX调用发送到Web服务器的最简单方法。请记住,AJAX调用不能发送到与加载AJAX调用的HTML页面所加载的域不同的域。例如,如果HTML页面是从jenkov.com加载的,则该HTML页面只能对jenkov.com域内的URL进行AJAX调用。

这是一个完整的AngularJS应用程序,带有一个$ httpAJAX示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
</head>

<body ng-app="myapp">

  <div ng-controller="MyController" >
    <button ng-click="myData.doClick(item, $event)">Send AJAX Request</button>
    <br/>
    Data from server: {{myData.fromServer}}
  </div>

  <script>
    angular.module("myapp", [])
        .controller("MyController", function($scope, $http) {
            $scope.myData = {};
            $scope.myData.doClick = function(item, event) {

                var responsePromise = $http.get("/angularjs-examples/json-test-data.jsp");

                responsePromise.success(function(data, status, headers, config) {
                    $scope.myData.fromServer = data.title;
                });
                responsePromise.error(function(data, status, headers, config) {
                    alert("AJAX failed!");
                });
            }

        } );
  </script>

</body>

</html>

注意在模块中注册的控制器功能如何使用两个参数:$ scope对象(一如既往)和一个额外的$ http对象。 $ http对象(或者"服务")用于进行AJAX调用。

$ http.get()函数返回一个" promise"对象。这个promise对象具有一个" success()"和一个" error()"功能。通过调用这些函数并将函数作为参数传递给它们,我们可以控制AJAX调用完成时发生的情况。如果AJAX调用成功(服务器发送回200至209之间的HTTP代码),则将执行传递给success()函数的函数。如果AJAX调用失败(除重定向以外的所有其他代码),则执行传递给error()方法的函数。稍后将更详细地介绍Succss()和error()函数。

$ http函数

$ http服务具有几个可用于发送AJAX请求的功能。这些是:

  • $ http.get(URL,config)
  • $ http.post(URL,数据,配置)
  • $ http.put(URL,数据,配置)
  • $ http.delete(URL,config)
  • $ http.head(URL,config)

注意,$ http.post()和$ http.put()函数采用一个data参数,该参数包含要发送到服务器的数据。其余的$ http函数不能使用data参数。

data参数将转换为JSON字符串。当HTTP请求发送到服务器时,此字符串将包含在请求正文中。 AngularJS将所有以$开头的属性视为私有,因此将它们从字符串中排除。如果我们需要在数据字符串中包含以$开头的属性,请使用JSON.stringify(data)自己将data对象转换为字符串。

$ http作为函数

我们也可以将$ http服务直接用作函数,如下所示:

var promise = $http(config);

在这种情况下,URL和HTTP方法也在config对象中设置。 config对象在下一节中说明。

配置参数

传递给不同的$ http函数的config参数控制发送到服务器的HTTP请求。 config参数是一个JavaScript对象,可以包含以下属性:

  • method
  • url
  • params
  • headers
  • timeout
  • cache
  • transformRequest
  • transformResponse

" method"属性可用于设置请求请求的HTTP方法。该方法是GET,POST,PUT,DELETE或者HEAD之一。通常通过选择在$ http服务上调用的函数来隐式设置此属性,因此在实践中几乎不需要设置此属性。

url属性可用于设置AJAX调用的URL。这已经提供给各种$ http函数,因此我们几乎不需要在config对象中再次设置它。

" params"属性用于设置任何添加到URL查询字符串的添加请求参数。 " params"属性是一个JavaScript对象,每个请求参数都需要添加一个属性。

标头属性用于设置要发送到服务器的任何其他HTTP标头。 " headers"属性是一个JavaScript对象,每个header具有一个属性。

timeout属性用于设置AJAX调用的超时时间。当达到超时限制时,AJAX调用将中止。超时以毫秒为单位。

" cache"属性用于启用XHR GET请求缓存。

" transformRequest"属性用于设置一个函数,该函数可以在将请求对象发送到服务器之前对其进行转换。

" transformResponse"属性用于设置一个函数,该函数可以转换从服务器发送回的响应,然后再传递给应用程序。

Promise对象的success()和error()函数

如前所述,$ http服务上的各种AJAX函数都返回一个Promise对象。这个Promise对象有两个函数,分别称为success()error()。这两个函数均以回调函数为参数。如果AJAX请求成功,则执行传递给success()函数的回调函数。如果AJAX请求失败,则调用传递给error()函数的回调函数。

success()error()函数内部,应该在$ scope对象上设置适当的值。这是将数据或者错误消息发送给用户的方法。用数据更新$ scope对象,AngularJS将触发HTML模板渲染,以便使数据对用户可见。

这两个函数均采用以下参数:

  • data
  • status
  • headers
  • config

data参数是服务器返回的JSON对象。 $ http服务假定服务器发回JSON。

" status"参数是服务器与响应一起返回的HTTP状态代码。

" headers"参数是一个函数,可用于获取与响应一起返回的任何HTTP响应标头。我们可以通过调用headers([headerName]);获得标题。如我们所见,headers()函数将标头名称数组作为参数。 AngularJS文档对函数返回的内容有点含糊,但我怀疑它会返回一个JavaScript对象,该对象带有一个键,每个标头都有值对,标头名称作为键(属性名称)。

config参数是用于创建给定HTTP请求(AJAX调用)的配置对象。换句话说,将config对象作为参数传递给创建此AJAX调用的$ http ajax函数调用,并由此创建该promise对象。

AngularJS和JSONP

AngularJS的$ http服务还能够发送JSONP请求。普通的AJAX调用只能将请求发送到与发送请求的HTML页面相同的域内的URL。我们可以使用JSONP请求解决此问题。

JSONP是"带有填充的JSON"的缩写(稍后我将解释原因)。 JSONP请求不会像通常的AJAX调用那样通过XHR对象发送。而是创建一个<script>元素并将其插入HTML页面。这是一个这样的<script>元素外观的示例:

<script src="http://jenkov.com/theService.json?callback=theServiceResponse&p1=v1&p2=v2"></script>

src属性包含要通过JSONP调用进行调用的远程服务的URL。该URL应该包含我们需要发送到远程服务的所有参数。

当将<script>元素插入HTML页面时,浏览器将从给定的URL加载脚本。这使远程服务可以将JavaScript发送回应用程序以执行。

远程服务返回的JavaScript应该是对HTML页面中现有JavaScript函数的函数调用。这是返回的JavaScript的外观:

theServiceResponse( { name : "John", title : "CEO", company : "BigFatCo" } );

该代码对名为" theServiceResponse"的函数进行函数调用。此功能必须已经存在于HTML页面中。在此功能内,我们可以处理从服务发送回的响应。

当调用theServiceResponse()函数时,会将JavaScript对象作为参数传递给该函数。此JavaScript对象包含来自服务调用的响应参数。因此,此JavaScript对象是由远程服务生成的。远程服务想要发回给东西都是此JavaScript对象包含的内容。从远程服务的角度来看,JavaScript对象就是JSON,就像发送回HTML页面的任何其他JSON一样。区别在于此JSON对象包装在函数调用中。此函数调用是JSONP的"带有填充的JSON"名称的"填充"部分。

我们可能想知道远程服务如何知道用于包装返回的JSON的函数的名称。答案是,将名称与其他请求参数一起传递给远程服务。函数名称是请求参数之一。默认情况下,此参数名称为callback,但我们必须与具体服务进行核对,以查看其对函数名称的期望参数名称。

在AngularJS中,函数名称由AngularJS在后台提供,因此我们不必担心将其添加到远程服务的URL中。

我们可以通过$ http服务使用JSONP调用,如下所示:

$http.jsonp( url, config );

像AJAX函数一样,jsonp()函数采用一个url和一个config对象。这是提供了urlconfig对象的JSONP调用示例:

var url = http://jenkov.com/theService.json?callback=JSON_CALLBACK";
var responsePromise = $http.jsonp( url,
             {  params : {
                   p1 : "v1"
                  ,p2 : "v2"
                }
              }
            );

responsePromise.success(function(data) {
    // do something with the returned JavaScript object
    // ( in the "data" parameter ).
});

本示例对服务URLhttp:// jenkov.com / theService.json进行JSONP调用。像$ http服务的其他AJAX函数一样,config对象可以包含params字段。该字段应该是一个JavaScript对象,其中包含所有要添加到远程服务URL的请求参数。

当我们调用$$。jsonp()函数时,AngularJS将为我们创建&lt;script>元素,并将其插入HTML页面。 AngularJS还将通过将config.params对象中传递的参数添加到URL来创建远程服务的最终URL。

传递给$$。jsonp()函数的URL必须包含callback = JSON_CALLBACK参数。 AngularJS会将JSON-CALLBACK字符串替换为AngularJS创建的回调函数的名称。

由$$。jsonp()函数返回的Promise对象具有一个success()函数,就像其他AJAX函数调用promise对象一样。不幸的是,当评估<script src =" url">元素时,由于该请求由浏览器在内部处理,因此我们无法访问从服务器发送回的响应的HTTP标头。这也意味着,如果JSONP调用失败,我们将无法得知,因为在这种情况下将不会调用回调函数(无法从远程服务执行JavaScript)。

JSONP安全性

我们必须谨慎对待JSONP调用。当我们进行JSONP调用时。远程服务可以发回任何JavaScript,然后这些JavaScript将在HTML页面内执行。恶意的远程服务可能会发回JavaScript,从而试图从应用程序中窃取信息并将其发送给第三方服务。仅对我们信任的服务进行JSONP调用。