什么是 AJAX,它是如何工作的?

IT技术 javascript jquery ajax
2021-02-05 13:05:13

可能的重复:
AJAX 是如何工作的?

注意:这是一个社区维基帖子

我经常听说 AJAX 用于为用户提供动态内容。它是什么以及它是如何工作的?

1个回答

AJAX 或 (A) 同步 (J)avascript (A)nd (X)ML(有趣的是,如今更倾向于使用 JSON)是一种系统,其中 Javascript 使用浏览器对象与远程服务器进行通信。其一般用例是无需转到另一个页面即可更新客户端的界面。在我们开始之前,请注意几句话。

  • 不建议将 Ajax 用于登录身份验证和发布表单
  • 用户可以关闭 Javascript,或者可能因 IT 政策而被限制运行 Javascript
  • 考虑到这一点,建议您不要使用 AJAX 作为关键用户功能的唯一解决方案!总有退路!

注意:此社区 wiki 帖子使用 JQuery 显示示例 AJAX 调用。推荐给新手,因为它隐藏了进行 AJAX 调用的浏览器兼容性问题。有关JQuery的更多信息,请查看JQuery 网站

注意:这些示例使用与 PHP 服务器的通信,但任何服务器端语言都可以使用。

AJAX 回调

首先,我们有一个 AJAX 调用。在 AJAX 调用中,您可以为可能发生的不同类型的事件设置回调处理程序。下面的代码显示了一个常见的误解:

// Incorrect!
function makeAjaxCall() {
  var result = $.ajax({
    url: 'ajax/test.html'
  });

  return result;
}

这里的问题是,当您的浏览器发出 AJAX 请求时,它可能会成功返回,也可能会失败。例如,如果您尝试访问不存在的页面,或者服务器出现内部错误。为了使事情尽可能有条理,AJAX 要求您创建回调函数来处理数据请求。正确的方法如下:

// Correct!
function makeAjaxCall() {
  $.ajax({
    url: 'ajax/test.html',
    success: function(data) {
      alert('Horray the AJAX call succeeded!');
    },
    error: function(xhr, error) {
      alert('Holy errors batman!');
    }
  });
}

AJAX 调用的性质

AJAX 调用可以是异步的,也可以是同步的。异步意味着浏览器将发出 AJAX 请求并继续做其他事情。同步意味着浏览器将停止正在执行的操作,直到 AJAX 调用完成。这是两个代码明智差异的示例:

// An asynchronous call
// This is the default
$.ajax({
  url: '/server.php',
  success: function(data) {
    alert('Horray the AJAX call succeeded!');
  },
  error: function(xhr, error) {
    alert('Holy errors batman!');
  }
});
// This will get called right away
myFunction();

现在进行同步调用:

// A synchronous call
$.ajax({
  url: '/server.php',
  async: false, // set the property here
  success: function(data) {
    alert('Horray the AJAX call succeeded!');
  },
  error: function(xhr, error) {
    alert('Holy errors batman!');
  }
});
// This won't get called until the AJAX returns!
myFunction();

警告:同步调用使得浏览器在浏览器完成调用之前不能做任何事情。这可能会锁定浏览器!仅当您真的知道自己在做什么时才使用它!99% 的情况下您都需要异步 AJAX 调用。

注意:同步调用并不意味着您可以不设置回调处理程序。您仍然必须使用回调处理结果。

客户端->服务器通信路径

AJAX 客户端服务器通信路径

此图说明了如何使用 AJAX 与远程服务器进行通信。首先,AJAX 代码与浏览器对象接口,后者对服务器进行实际调用。然后服务器处理请求并将结果发送回浏览器,浏览器然后查看调用结果以确定它是否需要调用成功处理程序或错误处理程序。但是,有一个问题可以完全阻止通信,这就是通常所说的同源策略。

注意从服务器的角度来看,AJAX 调用看起来就像是客户端手动发出请求一样。这意味着服务器可以利用诸如会话和其他客户端特定数据之类的东西。

同源政策

同源策略基本上意味着,如果您的 AJAX 调用来自托管在 上的页面http://www.mysite.com,则无法调用http://www.othersite.com如下所示:

阻止请求的同源策略

解决此问题的一种方法是通过代理服务。这是您与同一服务器上的脚本交互的地方,该脚本又与您希望的站点交互,例如通过 CURL 调用。下面说明了这个有问题的代理方法:

同源代理解决方法

警告请注意,第三方服务器不会将请求视为来自客户端,而是来自服务器。一些服务器不喜欢同一个 IP 向他们的服务器发出多次调用。这可能会使您被阻止,因此请验证相关站点是否适合此设置。

注意:在某些情况下,同源策略不适用,例如 Google Chrome 扩展程序调用(尽管您必须为每个站点设置权限)、某些 Greasemonkey 调用和 Adob​​e Air。

现在要讨论的最后一个概念是服务器如何返回数据以供客户端交互。

AJAX 数据返回

由于这是一个非常流行的选项,我们将使用 JSON 或 (J)ava(S)cript (O)bject (N)otation 来传回数据。JSON 基本上是这样的:

{
    color: "red",
    value: "#f00"
}

此字符串可以转换为 JavaScript 对象,从而可以轻松访问服务器结果。

警告由于这是有效的 JavaScript,许多人使用eval()快速创建 js 对象。请不要这样做如果结果中包含恶意代码,则会导致您面临安全问题。始终使用检查安全数据的 JSON 解析器!

使用前面的示例,我们可以像这样访问不同的值:

$.ajax({
  url: '/server.php',
  // It's a good idea to explicitly declare the return type
  dataType: 'json',
  success: function(json) {
    alert("The color is: " + json.color + " and the value is: " + json.value);
  },
  error: function(xhr, error) {
    alert('Holy errors batman!');
  }
});

请注意访问返回值是多么容易。另一个流行的选择是从服务器检索 HTML 并将其注入到一个<div>或其他元素中。这是一个例子:

$.ajax({
  url: '/server.php',
  // It's a good idea to explicitly declare the return type
  dataType: 'html',
  success: function(html) {
    $("#mydiv").html(html);
  },
  error: function(xhr, error) {
    alert('Holy errors batman!');
  }
});

// Some JS/HTML here

<div id="mydiv"></div>

在成功返回的情况下,<div>将使用返回 HTML 填充的内容

待办事项:如何防止恶意 HTML 注入?

结论

关于 AJAX 的社区 wiki 帖子到此结束。我希望它有助于帮助您理解 AJAX,或者作为回答有关它的常见问题的简单方法。

原始 XMLHTTPRequests 并没有那么糟糕。学习 $.ajax 或 XMLHTTPRequest 都同样令人困惑。
2021-03-14 13:05:13
@Raynos 正如所指出的,“这个社区 wiki 帖子使用 JQuery 来展示 AJAX 调用示例。建议新手使用,因为它隐藏了进行 AJAX 调用的浏览器兼容性问题。请查看 JQuery 网站以获取有关 JQuery 的更多信息。” 我可以展示如何制作一个非基于库的示例,但这可能会让那些只想了解 AJAX 工作原理的人感到困惑。
2021-03-15 13:05:13
@Raynos——是的,如这篇博文所示,POJS 请求不需要比库请求更多的代码,尤其是在 IE 6 消亡之后。使用一些(现在无处不在的)ECMAScript 2011 功能和可以更短,更语义。
2021-03-26 13:05:13
示例是否必须与 jQuery 结合?
2021-03-29 13:05:13
您可能想撰写有关 jQuery 的新 Deferred 对象的文章。
2021-04-04 13:05:13