精通jQuery AJAX:异步请求完全指南

本文深入探讨jQuery的$.ajax()函数,涵盖其配置选项、实际应用场景、错误处理策略、性能优化技巧以及现代替代方案,帮助开发者全面掌握异步HTTP请求的实现方法。

精通jQuery AJAX:异步请求完全指南

Ajax是一种允许开发者向服务器发起异步HTTP请求以检索或发送数据而无需完全刷新页面的技术。长期以来,开发者一直使用jQuery来简化这一过程,使其比纯JavaScript更加便捷。

在我之前的文章《jQuery简写Ajax方法介绍》中,我讨论了jQuery中最常用的一些Ajax调用,包括$.get()、$.post()和$.load(),这些方法只需几行代码即可在jQuery中方便地进行Ajax请求。但有时我们需要对Ajax调用进行更多控制。例如,我们需要指定Ajax请求失败时应执行的操作,或者需要执行Ajax调用函数但仅在一定时间内获取结果时才需要其结果。在这种情况下,我们可以依赖jQuery中Ajax提供的另一个函数$.ajax(),这也是本教程的主题。

关键要点

  • 多功能性和控制:jQuery $.ajax()函数提供了一种灵活而强大的方式进行异步HTTP请求,允许开发者广泛控制请求和响应过程。它支持多种设置,如指定成功和错误的回调函数、设置请求头、处理数据类型以及为HTTP访问认证请求添加认证令牌,这使其能够适应各种场景,超越了$.get()、$.post()和$.load()等简写Ajax调用函数的能力。

  • 全面的配置选项:文章重点介绍了$.ajax()可用的全面配置选项列表,几乎可以满足进行Ajax调用时可能遇到的任何需求。从修改请求头到处理响应数据,从处理错误到设置跨域请求,$.ajax()为开发者提供了必要的工具,以精确调整其Ajax请求和响应以满足应用程序的需求。

  • 在现代开发中的相关性:尽管出现了如Fetch等新API,jQuery $.ajax()函数在Web开发中仍然是一个相关且有价值的工具,特别是在维护遗留代码库或偏好jQuery提供的简单性和一致性的开发者中。其易用性结合功能的深度,确保$.ajax()在需要Ajax调用的项目中仍能发挥关键作用,突显了jQuery在Web开发生态系统中的持续实用性。

  • 高级错误处理和重试策略:通过使用指数退避的重试机制演示了强大的错误处理,确保应用程序能够优雅地从临时网络或服务器故障中恢复。开发者还可以定义全局错误处理程序来调试和跟踪多个请求中的错误。

$.ajax()函数

jQuery $.ajax()函数用于执行异步HTTP请求。它早在版本1.0时就已添加到库中。$.ajax()函数是$.get()、$.post()和$.load()在幕后使用预设配置进行调用的基础。该函数的签名如下所示:

1
2
$.ajax(url[, settings])
$.ajax([settings])

Ajax参数中的URL是一个字符串,包含您希望通过jQuery Ajax调用访问的URL,而settings是一个包含Ajax请求配置的对象字面量。

在第一种形式中,此函数使用URL参数和设置中指定的选项执行Ajax请求。在第二种形式中,URL在设置参数中指定或可以省略,在这种情况下,请求将发送到当前页面。

此函数接受的选项列表非常长,因此我将保持其描述简短。如果您想深入研究它们的含义,可以参考$.ajax()的官方文档。

设置参数

您可以指定许多不同的选项来使$.ajax()满足您的需求。在下表中,您可以按字母顺序找到它们的名称和描述:

参数 默认值 可能值 描述和用例
accepts { “”: “/*” } 任何MIME类型字符串 在请求头中发送的内容类型,告诉服务器它将接受何种类型的响应。
beforeSend 函数 一个预请求回调函数,可用于在发送前修改jqXHR对象。
cache true(脚本除外) true或false 将此选项设置为false以强制请求的页面不被浏览器缓存。
complete 函数 请求完成时调用的函数(在成功和错误回调执行后)。
contentType “application/x-www-form-urlencoded; charset=UTF-8” MIME类型字符串 发送到服务器的数据的内容类型。
context window 任何对象 用作所有Ajax相关回调的上下文(this)的对象。
converters 取决于dataType 对象映射 包含数据类型到数据类型转换器的对象。
crossDomain false true或false 将此属性设置为true以在同一域上强制跨域请求。
data 对象、字符串或数组 执行Ajax请求时发送到服务器的数据。
dataFilter 函数 用于处理XMLHttpRequest原始响应数据的函数。
dataType text xml、html、json、text等 期望从服务器返回的数据类型。避免使用jsonp请求,因为它已基本过时。
error 函数 请求失败时调用的函数。
global true true或false 是否为此请求触发全局Ajax事件处理程序。
headers 对象 要发送到服务器的附加头对象。
ifModified false true或false 仅当响应自上次请求以来已更改时才处理响应。
isLocal 取决于环境 true或false 强制jQuery将当前环境视为本地环境。
mimeType MIME类型字符串 指定用于覆盖XHR mime类型的mime类型的字符串。
password 字符串 用于XMLHttpRequest以响应HTTP访问认证请求的密码。
processData true true或false 确定是否应自动将数据序列化为查询字符串。
scriptCharset 字符串 设置请求中使用的脚本标签的charset属性,但仅在使用“脚本”传输时适用。
statusCode 对象 将HTTP状态码映射到回调函数。
success 函数 请求成功时调用的函数。
timeout 0(无超时) 整数 指定请求超时(以毫秒为单位)的数字。
type “GET” “GET”、“POST”等 要发出的请求类型。
url 当前页面URL 字符串 包含请求发送到的URL的字符串。
username 字符串 用于XMLHttpRequest以响应HTTP访问认证请求的用户名。
xhr 函数 用于创建XMLHttpRequest对象的回调函数。
xhrFields 对象 设置在原生XHR对象上的对象。

这是一个相当长的列表,不是吗?好吧,作为开发者,您可能在第5或第6个元素时就停止阅读这个列表了,我想,但这没关系。下一节将更加令人兴奋,因为我们将把$.ajax()函数及其一些选项付诸实践。

付诸实践

在本节中,我们将详细讨论$.ajax()函数及其一些选项的实际应用。

$.ajax()的第一个示例

我们将从一个简单的演示开始,重现我们在上一篇文章中开发的相同代码。作为回顾,我们将假设我们的网站中有一个ID为main的元素,代表主要内容。我们想要做的是异步加载主菜单中链接所引用页面的主要内容,理想情况下,主菜单的ID为main menu。我们只想检索此元素内的内容,因为布局的其他部分没有变化,因此不需要加载。

这种方法旨在作为一种增强,因为如果访问网站的用户禁用了JavaScript,他们仍然能够使用通常的同步机制浏览网站。在此示例中,我们假设菜单中的所有链接都是内部链接。

我们将从一个简单的演示开始,重现我们在上一篇文章中开发的相同代码,但这次我们将采用$.ajax()。为方便起见,我们之前开发的代码如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$('#main-menu a').on('click', function(event) {
  event.preventDefault();

  $('#main').load(this.href + ' #main *', function(responseText, status) {
  if (status === 'success') {
    $('#notification-bar').text('The page has been successfully loaded');
  } else {
      $('#notification-bar').text('An error occurred');
    }
  });
});

更新此代码片段以使用$.ajax()函数,我们获得如下所示的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$('#main-menu a').on('click', function(event) {
  event.preventDefault();

  $.ajax(this.href, {
    success: function(data) {
      $('#main').html($(data).find('#main *'));
      $('#notification-bar').text('The page has been successfully loaded');
},
    error: function() {
      $('#notification-bar').text('An error occurred');
    }
  });
});

在这里,您可以看到我使用了函数的第一种形式。我将URL指定为第一个参数,然后将设置对象作为第二个参数。后者利用了上一节讨论的几个属性中的两个——success和error——分别指定在请求成功或请求失败时应执行的操作。

添加自定义头和处理HTTP访问认证请求

在此第二个示例中,我们将探讨如何通过添加自定义头、处理认证令牌以及与需要特定安全措施的API交互来增强您的AJAX请求。这些是在与现代Web应用程序通信外部API时的常见场景。

假设您正在与一个需要令牌进行HTTP访问认证请求的API交互。您可以使用$.ajax()中的headers选项将此令牌作为请求头的一部分包含:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$('#main-menu a').on('click', function(event) {
  event.preventDefault();

  $.ajax({
    url: this.href,
    headers: {
      "Authorization": "Bearer YOUR_TOKEN_HERE",
      "X-Custom-Header": "CustomValue"
    },
    success: function(data) {
      $('#main').html($(data).find('#main *'));
      $('#notification-bar').text('The page has been successfully loaded with custom headers');
    },
    error: function() {
      $('#notification-bar').text('An error occurred while loading the page with custom headers');
    }
  });
});

在此示例中,Authorization头包含一个承载令牌,通常用于安全地与API认证请求。此外,X-Custom-Header作为额外的元数据头,通常由专有API要求以提供额外上下文或符合特定的服务器要求。

添加自定义头在与安全API合作时特别有用,确保适当的认证并向服务器提供任何必要的上下文信息。

使用$.ajax()管理复杂数据结构

API通常需要结构化数据,如嵌套JSON对象,以处理过滤器或分层信息。以下示例演示了如何使用$.ajax()函数的data属性发送结构化数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$.ajax({
  url: '/api/products',
  headers: {
     "Authorization": "Bearer YOUR_TOKEN_HERE",
     "X-Custom-Header": "CustomValue"
  },
  type: 'POST',
  contentType: 'application/json', // 指定JSON格式
  data: JSON.stringify({
    category: 'electronics',
    filters: {
      brand: 'Samsung',
      priceRange: [100, 500]
    }
  }),
  success: function(data) {
      $('#main').html($(data).find('#main *'));
      $('#notification-bar').text('The data has been sent successfully');
    },
    error: function() {
      $('#notification-bar').text('An error occurred while sending data');
    }
});

这里,contentType: ‘application/json’指定了发送的数据格式,JSON.stringify()将JavaScript对象转换为JSON字符串以与API兼容。这对于需要复杂查询或分层过滤器的API是理想的。

实际应用场景:实时搜索功能

既然您了解了$.ajax()的工作原理,让我们来看一个实际场景,其中$.ajax()非常有用。例如,假设您正在构建一个在线商店,并且希望用户在搜索框中输入时动态搜索产品。而不是每次重新加载整个页面,搜索结果应立即出现,为用户提供流畅和交互式的体验。

工作原理

当用户在搜索框中输入时,他们的查询字符串通过AJAX请求发送到服务器。服务器处理查询字符串并返回匹配的产品,这些产品立即显示在页面上。这保持了体验的快速和无缝。

以下是您可以处理的方式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$('#search-box').on('input', function() {
  let query = $(this).val().trim();

  if (query.length > 2) { // 仅对有意义的输入进行搜索
    $.ajax({
      url: "/search-products",
      type: "GET",
      data: { query: query },
      success: function(response) {
        let results = response.products.map(product => `
          <div class="product">
            <h3>${product.name}</h3>
            <p>${product.description}</p>
            <span>Price: $${product.price}</span>
          </div>
        `).join('');
        $('#search-results').html(results); // 动态显示结果
      },
      error: function() {
        $('#search-results').html('<p>Unable to load results. Please try again.</p>');
      }
    });
  } else {
    $('#search-results').empty(); // 清除短查询的结果
  }
});

为什么这很重要

想想用户在不重新加载页面以查看搜索结果时节省了多少时间。这种方法:

  • 增强可用性:结果实时出现,使界面感觉更加响应。
  • 节省带宽:仅获取所需数据,减少服务器上的不必要负载。
  • 改善用户体验:更快、更流畅的交互使用户保持参与。

通过应用这种简单模式,您可以将基本搜索框转换为动态、用户友好的功能,提升您的Web应用程序。

安全可靠AJAX请求的最佳实践

为确保您的AJAX请求安全可靠,遵循解决常见安全问题和优化开发过程的最佳实践非常重要。

错误处理策略

  • 使用错误回调函数或全局处理程序实施强大的错误处理,以向用户提供有意义的反馈并优雅地处理重试。
  • 避免无限重试以防止服务器过载;相反,实施如指数退避等策略。

跨域请求和安全考虑

  • 使用跨域资源共享(CORS)安全地处理跨域请求。确保服务器明确允许来自受信任源的请求。
  • 通过转义或清理输入和输出来防止跨站脚本(XSS)攻击。使用如DOMPurify等工具在处理前清理用户输入。
  • 在客户端和服务器端验证所有用户输入,以确保仅处理预期数据。
  • 始终通过HTTPS传输敏感数据,以保护传输中的数据并防止窃听或中间人攻击。

提高AJAX安全性

  • 使用如DOMPurify等库清理用户输入并防止XSS攻击。let cleanInput = DOMPurify.sanitize(userInput);
  • 使用如内容安全策略(CSP)等HTTP头来缓解注入攻击。
  • 实施反CSRF令牌以防止跨站请求伪造攻击。$.ajax({ url: '/secure-endpoint', type: 'POST', headers: { 'X-CSRF-Token': csrfToken }, data: { input: cleanInput } });
  • 通过将敏感API密钥安全地存储在服务器端来避免在前端暴露它们。
  • 定期审计和更新您的依赖项,包括jQuery,以解决已知漏洞。

调试Ajax请求:请求失败时该怎么办

调试Ajax jQuery请求有时可能很棘手,因为它们的异步性质以及涉及客户端和服务器端代码。以下是一些调试与jQuery $.ajax()方法相关问题的有效提示:

  1. 使用浏览器开发者工具

    • 网络选项卡:检查浏览器开发者工具中的网络选项卡以检查Ajax请求。验证请求URL、头、负载和响应。查找任何错误或意外状态码。
    • 控制台选项卡:在控制台选项卡中查找可能指示您的jQuery Ajax调用或其回调函数问题的JavaScript错误或警告。
  2. 检查服务器端日志

    • 如果jQuery Ajax调用到达服务器但行为不符合预期,检查服务器端日志以查找错误或警告。这可以提供有关服务器端代码或配置中问题的线索。
  3. 记录请求和响应

    • 临时在$.ajax()调用的success、error和complete回调中添加console.log()语句以记录响应或任何错误消息。这可以帮助您了解服务器返回的内容或请求可能失败的原因。
  4. 验证数据类型

    • 确保您的$.ajax()调用中的dataType选项与服务器返回的实际数据类型匹配。此处的不匹配可能导致jQuery错误处理响应,从而引发意外行为。
  5. 单独测试API端点

    • 使用如Postman或curl等工具手动测试API端点。这可以帮助您验证API是否正常工作并了解预期的请求格式和响应数据。
  6. 验证JSON响应

    • 对于JSON数据,使用在线JSON验证器或调试工具验证响应以确保其格式正确。格式错误的JSON可能导致解析错误。
  7. 使用jQuery.ajaxError()进行全局错误处理

    • 在文档上绑定事件处理程序到ajaxError以全局捕获和处理Ajax请求错误。这可以帮助您识别和调试应用程序中失败的Ajax请求。
1
2
3
$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
    console.error("AJAX Request Failed: ", settings.url, thrownError);
});
  1. 简化和隔离
    • 简化您的$.ajax()调用或将其隔离在简单环境/页面中以验证其行为而不受其他脚本或Ajax调用的干扰。

有时,这些错误可能是由于网络问题而暂时的。实施具有递增延迟的重试(指数退避)可以自动处理这种情况并提高应用程序的可靠性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function ajaxWithRetry(url, retries, delay) {
  $.ajax({
    url: url,
    success: function(data) {
      console.log('Success:', data);
    },
    error: function() {
      if (retries > 0) {
        setTimeout(() => {
          ajaxWithRetry(url, retries - 1, delay * 2);
        }, delay);
      } else {
        console.error('Failed after retries');
      }
    }
  });
}
ajaxWithRetry('/fetch-data', 3, 1000);

该函数最多重试请求3次,每次失败后延迟加倍。这有助于处理网络故障或临时服务器不可用。

优化Ajax请求的性能

优化Ajax请求的性能对于创建快速和响应的Web应用程序至关重要。在使用jQuery $.ajax()函数时,考虑以下提示以增强性能:

  1. 使用GET检索数据

    • HTTP GET请求通常更快,并且可以被浏览器缓存。尽可能使用HTTP GET检索数据,并保留HTTP POST请求用于更改服务器状态的操作。
  2. 限制数据传输

    • 最小化负载大小:仅发送和接收必要的数据。大负载可能显著减慢您的应用程序。
    • 压缩数据:如果您的服务器和客户端支持,对请求和原始响应数据使用压缩技术。
  3. 缓存响应

    • **浏览器
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计