AngularJS AJAX
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对象。这是提供了url
和config
对象的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将为我们创建<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调用。