返回值:jqXHRjQuery.ajax(url, [settings])

执行异步 HTTP (Ajax) 请求。

jQuery 发送的所有 Ajax 请求,内部都会通过调用 $.ajax() 函数来实现。通常没有必要直接调用这个函数,可以使用几个已经封装的简便方法,比如 $.get().load()。如果你需要使用几个不常用的选项,那么可以使用 $.ajax() 来提高灵活性。

最简单的情况下, $.ajax() 可以不带任何参数直接使用:

$.ajax();

注意: 所有选项的默认值都可以通过 $.ajaxSetup() 函数来全局设置。

上面这个例子中,我们没用使用任何选项,于是默认会载入当前页面的内容,但载入的结果是无法使用的。如果想要进一步处理先前载入的数据,我们就需要使用回调函数来操作了。

jqXHR 对象

从 jQuery 1.5 开始$.ajax() 返回 jQuery XMLHttpRequest (jqXHR) 对象。该对象是浏览器原生的 XMLHttpRequest 对象的一个超集。例如,该对象包括 responseTextresponseXML 属性, 也包括一个 getResponseHeader() 方法。当传输机制不为 XMLHttpRequest 时,例如,当发送一个 JSONP 请求,返回一个脚本 tag 时,jqXHR 对象会尽可能的模拟原生的 XHR 功能。

从 jQuery 1.5.1 开始,jqXHR 对象还包括 overrideMimeType() 方法 (该方法在 jQuery 1.4.x 版本中也可用, 但在 jQuery 1.5 中被临时删除了)。.overrideMimeType() 方法可能在 beforeSend() 回调函数中使用, 例如,修改请求头中,返回数据的内容类型(Content-Type):

$.ajax({
  url: 'http://fiddle.jshell.net/favicon.png',
  beforeSend: function( xhr ) {
    xhr.overrideMimeType( 'text/plain; charset=x-user-defined' );
  }
}).done(function ( data ) {
  if( console && console.log ) {
    console.log("Sample of data:", data.slice(0, 100));
  }
});

从 jQuery 1.5 开始,$.ajax() 返回的 jqXHR 对象,实现了 Promise 接口, 使它拥有了 Promise 的所有属性,方法和行为。(详见 延迟对象 来获得更多信息)。为了让回调函数的名字统一,便于在 $.ajax() 里使用,jqXHR 同样也提供了 .error(), .success().complete() 方法。这些方法都带有一个参数,该参数是一个函数,此函数在 $.ajax() 请求结束时被调用,并且这个函数接收的参数,与调用 $.ajax() 函数时的参数是一致。这将允许你在一次请求时,对多个回调函数进行赋值,甚至允许你在请求已经完成后,对回调函数进行赋值(如果该请求已经完成,则回调函数会被立刻调用)。

弃用通知: jqXHR.success(), jqXHR.error()jqXHR.complete() 回调函数在 jQuery 1.8 中将被废弃。为日后代码兼容性考虑,请使用如下方法进行替代 jqXHR.done(), jqXHR.fail()jqXHR.always()

// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.ajax( "example.php" )
    .done(function() { alert("success"); })
    .fail(function() { alert("error"); })
    .always(function() { alert("complete"); });

// perform other work here ...

// Set another completion function for the request above
jqxhr.always(function() { alert("second complete"); });

为了 XMLHttpRequest 的向后兼容,jqXHR 对象将会暴露如下属性和方法:

  • readyState
  • status
  • statusText
  • responseXML and/or responseText 当请求返回的结果是 xml and/or text
  • setRequestHeader(name, value) 该方法用新值替换旧值,而不是将新值连接到旧值中
  • getAllResponseHeaders()
  • getResponseHeader()
  • abort()

不再提供 onreadystatechange 属性,因为不同的状态可以分别在 success, error, completestatusCode 方法中进行处理。

回调函数

beforeSend, error, dataFilter, successcomplete 等选项都可以接受一个函数,这个函数会在适当的时机执行。

从 jQuery 1.5 开始, error (fail), success (done) 和 complete (always, 从 jQuery 1.6 开始) 回调函数钩子采用了先进先出的队列管理方式。这意味着你可以为每个回调函数钩子添加多个回调函数。详见 延迟对象方法, 延迟对象方法已经为这些 $.ajax() 回调函数钩子做了内部实现。

this 会始终指向传递给 $.ajax 函数选项中的 context 属性所指向的对象。如果没有设置 context ,则 this 会指向 $.ajax 本身。

有些类型的 Ajax 请求,比如 JSONP 和跨域的 GET 请求,本身不使用 XHR。所以在这种情况下,传给回调函数的 XMLHttpRequesttextStatus 参数就是 undefined

下面是 $.ajax() 函数提供的回调函数:

  1. beforeSend 会在发送请求之前被调用,并将 jqXHR 对象和 settings 映射作为参数。
  2. error 会在请求失败时,按照它们被注册的顺序被调用。此方法接收如下三个参数:jqXHR 对象,描述错误类型的字符串,以及一个异常对象(如果有的话)。一些内建的错误会将 "abort", "timeout", "No Transport" 等字符串作为异常对象。
  3. dataFilter 会在请求成功并接收到返回数据之后被调用。此方法接收如下参数:请求到的数据以及 dataType 参数的值。并且必须返回一个新的数据(可以是处理过的),这个数据将传递给 success 回调函数做进一步处理。
  4. success 会在请求成功之后,按照它们被注册的顺序被调用。此方法接收如下三个参数:请求返回的数据,描述请求成功代码的字符串,以及 jqXHR 对象。
  5. complete 无论请求成败与否,它都会在请求结束后,按照它们被注册的顺序被调用。此方法接收两个参数:jqXHR 对象,以及一个包含成功或失败代码的字符串。

例如,如果想直接使用返回的 HTML,可以实现如下 success 函数:

$.ajax({
  url: 'ajax/test.html',
  success: function(data) {
    $('.result').html(data);
    alert('Load was performed.');
  }
});

如此简单的例子,还可以用更优雅的方式来替代: .load()$.get()

数据类型

$.ajax() 函数依赖服务器提供的信息来处理返回的数据。如果服务器报告说返回的数据是XML,那么返回的结果就可以用普通的XML方法或者 jQuery 的选择器来遍历。如果检测到到其他类型,比如上例中返回的HTML,则数据就以文本形式来对待。

通过设定 dataType 选项,可以指定成其他不同的数据类型。除了 xml, dataType 还可以是 html, json, jsonp, script, 或 text.

其中, textxml 类型返回的数据不会经过处理。数据仅仅简单的将 jqXHRresponseTextresponseXML 属性传递给 success 回调函数。

注意: 我们必须确保服务器端报告的 MIME 类型与我们选择的 dataType 类型相匹配。比如说,选择 XML 的话,为了与结果一致,服务器端就必须声明 MIME 类型为 text/xmlapplication/xml

如果指定为 html 类型,任何内嵌的 JavaScript 都会在 HTML 作为一个字符串返回之前被执行。类似的,指定 script 类型的话,也会先执行服务器端生成的 JavaScript 脚本,然后再把脚本作为一个文本数据返回。然后什么都不返回。

原文如下:If html is specified, any embedded JavaScript inside the retrieved data is executed before the HTML is returned as a string. Similarly, script will execute the JavaScript that is pulled back from the server, then return nothing.

如果指定为 json 类型,则会把获取到的数据作为一个 JavaScript 对象来解析,并且把构建好的对象作为结果返回。为了实现这个目的,首先尝试使用 jQuery.parseJSON()。 如果浏览器不支持,则使用一个 Function constructor。格式有误的 JSON 数据会抛出一个错误 (详见 json.org 获得更多帮助)。JSON 数据是一种能很方便通过 JavaScript 解析的结构化数据。如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用 jsonp 类型来代替。

使用 jsonp 类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的 URL 后面。服务器端应当在 JSON 数据前加上回调函数名,以便完成一个有效的 JSONP 请求。如果要指定其它回调函数的参数名来取代默认的 callback,可以通过设置 $.ajax()jsonp 参数。

注意: JSONP 是 JSON 格式的扩展。它要求一些服务器端的代码来检测并处理查询字符串参数。更多信息可以参阅 最早关于 JSONP 的文章.

当数据需要从远端服务器上获得时(这只可能是用了 scriptjsonp 数据类型),则 error 回调函数和全局事件不会被调用。

向服务器发送数据

默认情况下,Ajax 请求使用 GET 方法。如果要使用 POST 方法,可以设定 type 选项。这个选项也会影响 data 选项中的内容如何被发送到服务器上。按照 W3C XMLHTTPRequest 的标准,POST 的数据始终是用 UTF-8 字符集传输的。

data 选项既可以包含一个查询字符串,比如 key1=value1&key2=value2,也可以是一个映射,比如 {key1: 'value1', key2: 'value2'}。如果使用了后者的形式,则数据在发送给服务器前会被 jQuery.param() 转换成查询字符串。这个处理过程也可以通过设置 processDatafalse 来回避。但如果我们希望发送一个 XML 对象给服务器时,这种处理就可能不合适了。在这种情况下,我们还应当设置 contentType 选项,使用其它合适的 MIME 类型,取代默认的 application/x-www-form-urlencoded

高级选项

global 选项用于在 Ajax 请求时,阻止响应全局注册的 Ajax 事件回调函数,比如 .ajaxSend() , .ajaxError() , 以及其他类似的方法。这在有些时候很有用,比如发送的请求非常频繁且简短的时候,就可以禁用 .ajaxSend() 里设置的载入等待指示器。当遇到跨域脚本或 JSONP 请求时,global 选项将自动被设置成 false。更多关于这些方法的详细信息,请参阅下面的内容。

如果服务器需要HTTP认证,可以使用用户名和密码。通过 usernamepassword 选项来设置。

Ajax请求是限时的,所以可以捕获并处理错误警告,来提供更好的用户体验。请求超时这个参数通常就保留其默认值,或者就通过$.ajaxSetup()来全局设定,很少为特定的请求重新设置 timeout 选项。

默认情况下,请求是总会被发出去的,但浏览器有可能从它的缓存中读取数据。要禁止使用缓存的结果,可以设置 cache 参数为 false。如果希望判断数据自从上次请求后是否被更改过,如果没有更改过就报告请求失败的话,可以设置 ifModified 参数为 true

scriptCharset 参数允许给 <script> 标签的请求设定一个特定的字符集,通常用于 script 或者 jsonp 类型。当脚本和页面字符集不同时,就可以使用这个参数。

Ajax 的第一个字母是 "asynchronous" 的首字母,这意味着所有的操作都是并行的,完成的顺序没有前后关系。$.ajax()async 选项默认值是 true,这意味着在请求开始后,其它代码依然能够执行。强烈不建议把这个选项设置成false(意味着所有的请求都不再是异步的),这会导致浏览器显得反应迟钝。

$.ajax() 函数返回它创建的 XMLHttpRequest对象。通常 jQuery 只在内部处理并创建这个对象,但用户也可以通过 xhr 选项来传递一个自己创建的xhr对象。返回的对象通常已经被丢弃了,但依然提供一个底层接口来观察和操控请求。比如说,调用对象上的 .abort() 可以在请求完成前中止请求。

到目前为止, 由于 Firefox 存在一个 bug,当 .getResponseHeader('Content-Type') 返回非空字符串时,.getAllResponseHeaders() 却返回空字符串。在 Firefox 下,jQuery 不支持自动解码 JSON CORS 返回结果。

下面是一个重写 jQuery.ajaxSettings.xhr 的例子:

var _super = jQuery.ajaxSettings.xhr;
jQuery.ajaxSettings.xhr = function () {
    var xhr = _super(),
        getAllResponseHeaders = xhr.getAllResponseHeaders;

    xhr.getAllResponseHeaders = function () {
        if ( getAllResponseHeaders() ) {
            return getAllResponseHeaders();
        }
        var allHeaders = "";
        $( ["Cache-Control", "Content-Language", "Content-Type",
                "Expires", "Last-Modified", "Pragma"] ).each(function (i, header_name) {

            if ( xhr.getResponseHeader( header_name ) ) {
                allHeaders += header_name + ": " + xhr.getResponseHeader( header_name ) + "\n";
            }
            return allHeaders;
        });
    };
    return xhr;
};

扩展 Ajax

从 jQuery 1.5 开始, jQuery 的 Ajax 实现了包括预过滤器,转换器和传输。允许您更加灵活的扩展 Ajax。更多的信息及相关高级特性,请参见如下页面 扩展 Ajax

补充说明:

  • 由于浏览器的安全限制,大多数 "Ajax" 请求都服从 同源策略(same origin policy)。即无法从不同的域,子域或协议中正确接收数据。
  • Script 和 JSONP 请求没有同源策略(same origin policy)的限制。

示例:

保存数据到服务器,成功时显示信息。

jQuery 代码:
$.ajax({
  type: "POST",
  url: "some.php",
  data: { name: "John", location: "Boston" }
}).done(function( msg ) {
  alert( "Data Saved: " + msg );
});

示例:

装载一个 HTML 网页的最新版本。

jQuery 代码:
$.ajax({
  url: "test.html",
  cache: false
}).done(function( html ) {
  $("#results").append(html);
});

示例:

发送 XML 数据至服务器。设置 processData 选项为 false,防止自动将数据格式转换成字符串。

jQuery 代码:
var xmlDocument = [create xml document];
var xmlRequest = $.ajax({
  url: "page.php",
  processData: false,
  data: xmlDocument
});

xmlRequest.done(handleResponse);

示例:

发送一个 id 数据到服务器,并在成功后通知用户。如果请求失败,则向用户发出警告。

jQuery 代码:
var menuId = $("ul.nav").first().attr("id");
var request = $.ajax({
  url: "script.php",
  type: "POST",
  data: {id : menuId},
  dataType: "html"
});

request.done(function(msg) {
  $("#log").html( msg );
});

request.fail(function(jqXHR, textStatus) {
  alert( "Request failed: " + textStatus );
});

示例:

加载并执行 JavaScript 文件。

jQuery 代码:
$.ajax({
  type: "GET",
  url: "test.js",
  dataType: "script"
});