jQuery AJAX
jQuery AJAX函数使我们可以在HTML页面中轻松使用AJAX。术语AJAX是异步Javascript和XML的缩写。 AJAX使得从后台服务器异步获取内容成为可能,并用新内容更新页面的所有部分,而不必重新加载完整的HTML页面。
jQuery AJAX示例
这是第一个jQuery AJAX示例,显示了如何在jQuery中进行AJAX调用:
var jqxhr = $.ajax({ url: "/theServiceToCall.html", data: { name : "The name", desc : "The description" } }) .done (function(data, textStatus, jqXHR) { alert("Success: " + response) ; }) .fail (function(jqXHR, textStatus, errorThrown) { alert("Error") ; }) .always(function(jqXHROrData, textStatus, jqXHROrErrorThrown) { alert("complete"); }) ;
首先调用$ .ajax()函数。向此函数传递一个JavaScript对象,该对象包含有关要进行的AJAX调用的信息。在示例中,此对象包含URL和要发送到服务器的数据。
$ .ajax()函数返回一个对象。在这个对象上,示例调用了三个函数:done(),fail()和always()。
函数done()
被赋予一个函数作为参数。如果AJAX请求成功,则执行作为参数传递给done()
函数的回调函数。回调函数获得三个参数:data,textStatus和jqXHR。 data参数是服务器返回的数据。 textStatus参数是服务器返回的文本状态消息。 jqXHR参数是jqXHR对象,它也由$ .ajax()函数返回。
还给fail()
提供了一个函数作为参数。如果AJAX请求失败,则作为参数传递给fail()
函数的回调函数将被调用。回调函数获得三个参数:jqXHR,textStatus和errorThrown。 jqXHR参数是jqXHR对象,它也是由$ .ajax()函数返回的。 " textStatus"是服务器返回的文本状态消息。 errorThrown
参数是jQuery抛出的错误。
每当AJAX请求完成时,无论AJAX请求是成功还是失败,都将调用传递给always()
函数的回调函数。传递给回调函数的三个参数将与传递给done()
或者fail()
的三个参数相同,这取决于AJAX请求是成功还是失败。
1.8.0之前的jQuery AJAX
在jQuery 1.8.0之前,从jQuery $ .ajax()函数返回的对象不包含done()
,fail()
和always()
函数。取而代之的是,这些函数被称为"成功()","错误()"和"完成()"。
1.8.0之后的jQuery AJAX
从jQuery 1.8.0开始,$ .ajax()函数返回一个jqXHR对象,该对象实现了promise接口(done(),fail(),always()等),而不是success()
,error()
和complete()
函数。现在不推荐使用success(),error()和complete()函数。我在有关jQuery延迟对象的文章中描述了promise接口。
使用AJAX接收HTML
默认情况下,jQuery AJAX函数不会解析从服务器接收到的数据。我们可以将其原始插入div
中,如下所示:
var jqxhr = $.ajax({ url: "/theServiceToCall.html", data: { name : "The name", desc : "The description" } }) .done (function(data) { $('#theDiv').html(data); }) .fail (function() { alert("Error") ; }) ;
请注意,done()函数如何选择ID为theDiv的div并调用其html()函数,并将从服务器接收的数据作为参数传递。
使用AJAX接收JSON
如果我们希望jQuery将从服务器接收到的数据解释为JSON,则必须将dataType:'json'
字段添加到作为参数传递给$ .ajax()调用的JavaScript对象中。假设我们从服务器返回了一个JSON对象,如下所示:
{ "param1" : "hello world" }
然后,我们可以通过$ .ajax()调用来解析该JSON对象并引用param1属性:
var jqxhr = $.ajax({ url: "/theServiceToCall.json", dataType: 'json', data: { name : "The name", desc : "The description" } }) .done (function(data) { alert("Success: " + data.param1) ; }) .fail (function() { alert("Error") ; }) ;
在AJAX请求中发送参数
我们可以通过jQuery的AJAX函数将参数发送到服务器。我们已经看到了这样的示例。这是传递给$ .ajax()函数的JavaScript对象的data属性,其中包含要发送到服务器的数据。这是一个用粗体标记的data对象的示例:
var jqxhr = $.ajax({ url: "/theServiceToCall.html", data: { name : "The name", desc : "The description" } }) .done (function(data) { alert("Success: " + data.param1) ; }) .fail (function() { alert("Error") ; }) ;
data属性应始终为JavaScript对象。它的属性被序列化为必需的查询字符串(用于GET请求)或者常规的帖子主体参数字符串(用于POST请求)。然后,此序列化的字符串与AJAX请求一起发送到服务器。
在服务器上,我们可以读取数据对象的属性,就像通过GET或者POST将其作为简单的请求参数发送一样。就像属性是表单中的字段一样。在上面的示例中,服务器将能够读取两个请求属性:name和desc。
在AJAX请求中发送原始数据
如果我们不希望jQuery将data
对象转换为序列化的参数字符串,则可以通过在传递给$ .ajax()函数的JavaScript对象中设置processData:false
来避免这种情况。这是一个例子:
var jqxhr = $.ajax({ url: "/test.jsp", processData : false, type : "POST", data: "THE DATA" }) .done (function(data) { $('#ajaxDiv').html(data) }) .fail (function() { alert("Error ") ; }) ;
注意将processData属性设置为false。这告诉jQuery在将data属性发送到服务器之前不要对其进行处理。
其次,注意" type"属性,该属性设置为" POST"。这告诉jQuery将数据发布到服务器。
第三,请注意data属性现在只是一个要发送到服务器的原始数据字符串。如果我们在发送数据之前未处理数据,则不能将JavaScript对象用作"数据"属性。
在AJAX请求中发送JSON
如果需要通过AJAX请求将JavaScript对象作为JSON字符串发送到服务器,则需要将JavaScript对象转换为JSON字符串并将字符串作为原始数据发送。这是一个jQuery JSON帖子示例:
var theObject = { p1: "v1", p2 : "v2 }; var jqxhr = $.ajax({ url: "/test.jsp", processData : false, type : "POST", data: JSON.stringify(theObject) }) .done (function(data) { $('#ajaxDiv').html(data) }) .fail (function() { alert("Error ") ; }) ;
HTTP GET和POST
HTTP请求可以作为GET,POST,PUT,DELETE或者HEAD请求发送。在这里,我将向我们展示如何执行GET和POST请求。由于AJAX请求是HTTP请求,因此我们还可以指定要与jQuery AJAX请求一起使用的HTTP方法。
如我们先前所见,可以通过其JavaScript参数对象将要使用的HTTP方法传递给$ .ajax()。我们可以通过设置参数对象的type
参数来实现。这首先是一个使用jQuery AJAX函数的HTTP GET示例:
var jqxhr = $.ajax({ url: "/target.jsp", type : "GET", data: { param1 : "value1", param2 : "value2" } }) .done (function(data) { /* process data */ }) .fail (function() { alert("Error ") ; }) ;
这是一个使用jQuery AJAX函数的HTTP POST示例:
var jqxhr = $.ajax({ url: "/target.jsp", type : "POST", data: { param1 : "value1", param2 : "value2" } }) .done (function(data) { /* process data */ }) .fail (function() { alert("Error ") ; }) ;
$ .get()和$ .post()函数
jQuery具有两个函数,可用于发送简化的HTTP GET和HTTP POST请求。这些函数是$ .get()和$ .post()函数。
这是显示如何使用jQuery的$ .get()函数的示例:
var parameters = { p1 : "val1", p2 : "val2"}; $.get("data.html", parameters ) .done(function(data) { $("#targetElement").html(data); }) ;
$ .get()函数将URL和请求参数对象作为参数。 $ .get()函数返回一个jqXHR对象,就像$ .ajax()函数一样。因此,响应的处理类似于使用$ .ajax()函数处理响应的方式。
jQuery的$ .post()函数以相同的方式工作。这是一个例子:
var parameters = { p1 : "val1", p2 : "val2"}; $.post("data.html", parameters ) .done(function(data) { $("#targetElement").html(data); }) ;
$ .getJSON()函数
$ .get()和$ .post()函数不处理服务器返回的数据。如果要将服务器返回的数据解释为JSON,则可以使用jQuery的$ .getJSON()函数:以下是$ .getJSON()示例:
var parameters = { p1 : "val1", p2 : "val2"}; $.getJSON("data.json", parameters ) .done(function(data) { $("#getJSONTarget").html(data.param1); }) ;
如我们所见,$ .getJSON()函数的函数与$ .get()和$ .post()函数的工作原理非常相似。唯一的区别是,通过done()
传递给回调函数集的data
参数现在是一个JavaScript对象。
load()函数
jQuery还有一个名为" load()"的函数,可以在选定的元素上调用它。 load()
元素通过AJAX加载一些HTML并将其插入到选定的元素中。这是一个jQueryload()
示例:
$("#loadTarget").load("html-fragment.html");
并带有请求参数:
var parameters = { p1 : "val1", p2 : "val2"}; $("#loadTarget").load("html-fragment.html", parameters);
并在load()
完成时调用一个回调:
var parameters = { p1 : "val1", p2 : "val2"}; $("#loadTarget").load("html-fragment.html", parameters, function() { console.log("load done"); });
我们也可以只插入一部分HTML。如果在url后面添加空格+ jQuery选择器字符串,则load()将仅插入与选择器匹配的已加载HTML的一部分。这是一个例子:
$("#loadTarget2").load("html-fragment.jsp #div2");
本示例加载HTML片段html-fragment.jsp,从该片段中选择ID为div2的元素,然后仅插入该元素,而不管HTML片段还包含什么内容。
注意:如果加载的HTML包含任何JavaScript,则将HTML插入目标HTML元素时将执行该JavaScript。但是,如果加载片段(URL + jQuery选择器),则在插入HTML之前,将删除在加载的文件中找到的所有JavaScript。通常,不要使用load()来加载JavaScript(除非我们绝对需要一起加载HTML和JavaScript)。 jQuery为此具有$ .getScript()函数。
$ .getScript()函数
jQuery中的$ .getScript()函数加载一个JavaScript文件并执行。该函数使用jQuery的基础AJAX函数,因此$ .getScript()
函数无法从其他域加载脚本,而不是从中加载请求的HTML页面(就像普通AJAX调用一样)。
这是一个jQuery.getScript()
示例:
$.getScript("sample-script.js");
带有参数示例的jQuery$ .getScript()
:
var parameters = {}; $.getScript("sample-script.js", parameters);
还有一个带有回调示例的jQuery$ .getScript()
:
var parameters = {}; $.getScript("sample-script.js", parameters, function() { console.log("sample-script.js loaded"); });
最后一个函数调用也可以在省略" parameters"对象的情况下使用。
全局AJAX函数
jQuery具有一组全局AJAX函数,我们可以使用它们在通过jQuery发送的所有AJAX请求中侦听AJAX事件。这些全局AJAX函数是:
- .ajaxSend()
- .ajaxStart()
- .ajaxStop()
- .ajaxSuccess()
- .ajaxError()
- .ajaxComplete()
在发送每个AJAX请求之前,将调用在ajaxSend()
函数中注册的回调函数。这是一个例子:
$(document).ajaxSend(function() { console.log("called before each send"); });
注意,在jQuery选择对象上调用了ajaxSend()。
如果当前没有正在执行的AJAX请求,则在发送AJAX请求之前,调用在ajaxStart()
函数中注册的回调函数。这是一个例子:
$(document).ajaxStart(function() { console.log("called before each AJAX request if no other request are executing"); });
如果没有其他正在执行的AJAX请求,则在AJAX请求完成后调用在`ajaxStop()函数中注册的回调函数。这是一个例子:
$(document).ajaxStop(function() { console.log("called after an AJAX request finishes, if no other request are executing"); });
每当AJAX请求成功时,都会调用在ajaxSuccess()
函数中注册的回调函数。这是一个例子:
$(document).ajaxSuccess(function(event, jqxhr, ajaxOptions, data) { console.log("called if an AJAX request succeeds"); });
每当AJAX请求失败时,都会调用在ajaxError()
函数中注册的回调函数。这是一个例子:
$(document).ajaxError(function(event, jqxhr, ajaxOptions, errorThrown) { console.log("called if an AJAX request fails"); });
每当AJAX请求完成时,无论AJAX请求成功还是失败,都将调用在ajaxComplete()函数中注册的回调函数。这是一个例子:
$(document).ajaxComplete(function(event, jqxhr, ajaxOptions) { console.log("called after an AJAX request completes"); });
jqXHR对象
jQuery的许多AJAX函数返回的jqXHR
对象包含一些有用的信息。注意,在Web服务器发送回响应之前,某些信息不可用,这意味着可以从done()
,fail()
或者always()
回调函数内部使用。
jqXHR对象包含以下属性和函数:
status
statusText
responseText
responseXML
getAllResponseHeaders()
getResponseHeader()
abort()
状态属性包含网络服务器发送回的HTTP状态代码(例如200或者404等)。
状态文本属性包含文本成功或者错误,具体取决于AJAX请求是成功还是失败。
如果响应以文本形式发送(例如,内容类型为文本/ html
,文本/纯文本
或者应用程序/ json
),则responseText
包含服务器发送回的HTTP响应的正文。
如果响应是以XML格式发送回去的,则responseXML属性包含服务器发送回的HTTP响应的正文(例如,内容类型为text / xml或者application / xml)。
getAllResponseHeaders()以字符串形式返回HTTP响应标头。每个标头在其自己的行中列出,并包含标头名称,冒号和标头值。例如:
Content-Encoding: gzip Server: Jetty(9.2.1.v20140609) Content-Length: 54 Content-Type: application/json
getResponseHeader()函数可用于访问各个HTTP响应标头。我们可以这样传递HTTP标头的名称:
var contentType = jqXHR.getResponseHeader("Content-Type");
jqXHR对象上的abort()函数可在完成之前中止AJAX(HTTP)请求。我们应该在调用任何done()
,fail()
或者always()
回调函数之前调用此函数。当服务器已发送回响应时,将调用这些回调函数,而此时中止AJAX调用为时已晚。
处理错误
如果AJAX请求失败,我们可以对通过$ .ajax()函数返回的对象的fail()
函数添加的回调函数内部的故障做出反应。这是一个jQuery AJAX错误处理示例:
var jqxhr = $.ajax({ url: "/this-page-does-not-exist.jsp", }) .done (function(data) { /* will never happen - page not found*/) .fail (function(jqxhr, textStatus, errorThrown) { alert("Error: " + textStatus + " : " + errorThrown) ; }) ;
如果上述AJAX请求中发生错误,传递给done()
函数的回调函数将被执行。在此回调函数中,我们可以处理错误。处理错误通常包括通知用户请求失败。本示例显示警报,但是我们也可以将错误消息插入页面中某个位置的HTML元素中。
记住,我们可以访问服务器响应返回的HTTP状态代码。在某些情况下,我们可能需要根据此代码的值做出不同的反应。这是一个简单的示例:
var jqxhr = $.ajax({ url: "/this-page-does-not-exist.jsp", }) .done (function(data) { /* will never happen - page not found*/) .fail (function(jqxhr, textStatus, errorThrown) { if(jqxhr.status == 404) { alert("page not found!"); } }) ;
我们还可以查看响应标头或者响应正文。这是一个例子:
var jqxhr = $.ajax({ url: "/this-page-does-not-exist.jsp", }) .done (function(data) { /* will never happen - page not found*/) .fail (function(jqxhr, textStatus, errorThrown) { var contentType = jqxhr.getResponseHeader("Content-Type"); var responseBody = jqxhr.responseText; //do something depending on response headers and response body. }) ;
ajaxError()
通常,我们将以相同的方式处理所有AJAX错误。不必在每个AJAX调用上都设置fail()
处理函数,我们可以使用全局函数ajaxError()
来处理单个AJAX错误回调函数。这是一个jQueryajaxError()
示例:
$(document).ajaxError(function(event, jqxhr, ajaxOptions, errorThrown) { var contentType = jqxhr.getResponseHeader("Content-Type"); var responseBody = jqxhr.responseText; //do something depending on response headers and response body. }); var jqxhr = $.ajax({ url: "/this-page-does-not-exist.jsp", }) .done (function(data) { /* will never happen - page not found*/) ;
请注意,没有fail()
处理函数添加到AJAX请求中。现在,所有AJAX请求的AJAX错误处理都由传递给$(document).ajaxError()的回调函数来处理。我们也可以在此回调中访问jqXHR
对象,以及产生失败请求的AJAX选项对象,等等。
$ .ajaxSetup()
$ .ajaxSetup()函数可用于设置所有AJAX调用使用的选项,包括通过$ .ajax(),load(),$。get()等执行的选项。我们可以设置的选项与传递给$ .ajax()调用的选项相同。例如,下面的示例将所有AJAX调用的type属性设置为POST:
$.ajaxSetup({ type : "POST" });
现在,所有AJAX调用都将是HTTP POST请求,除非请求明确覆盖了该属性。 AJAX请求可以像这样覆盖它:
$.ajax({ url : "the-service.json", type : "GET" });
通过在AJAX选项对象中显式设置type
属性,$。ajax()调用将通过$ .ajaxSetup()覆盖全局设置。
jQuery文档建议我们谨慎使用$ .ajaxSetup()
。设置全局选项可能导致无法预料的副作用(使用错误的选项触发AJAX请求)。
$ .ajaxPrefilter()
jQuery中的$ .ajaxPrefilter()函数用于设置预过滤函数,该函数可以在所有AJAX调用发送之前对其进行过滤。过滤是指传递给$ .ajax()函数的AJAX选项对象可以在发送请求之前进行更改("过滤")。
这是一个jQuery AJAX $ .ajaxPrefilter()示例:
$.ajaxPrefilter(function(options, originalOptions, jqXHR){ if(options.url.indexOf("/app") != -1) { options.type = "POST"; } });
这个示例设置了一个预过滤器函数,该函数检查options
对象的url
属性是否包含子字符串" / app"。如果是这样,则将options.type设置为POST。
传递给filter函数的options参数是options对象,该对象将由$ .ajax()函数处理。该对象包含通过$ .ajaxSetup()设置的设置和调用时传递给$ .ajax()函数的options对象的合并。
originalOptions对象包含传递给$ .ajax()函数的options对象,而从$ .ajaxSetup()设置的选项中未合并任何选项。
" jqXHR"对象是普通的" jqXHR"对象,将用于执行此AJAX请求。
$ .ajaxSetup()函数和$ .ajaxPrefilter()函数之间的主要区别在于,$ .ajaxSetup()函数采用静态选项对象作为参数。这些选项将应用于所有AJAX请求。 $ .ajaxPrefilter()将函数作为参数。与默认选项与请求选项的简单合并相比,函数可以对选项执行更智能的筛选。