什么是AJAX以及它是如何工作的?

ont*_*ia_ 2 javascript ajax jquery

可能重复:
AJAX如何工作?

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

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

ont*_*ia_ 48

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;
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,当您的浏览器发出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!');
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

现在进行同步通话:

// 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();
Run Code Online (Sandbox Code Playgroud)

警告:同步调用会使浏览器在浏览器完成调用之前无法执行任何操作.这可能会锁定浏览器!如果你真的知道你在做什么,只能使用它!99%的时间你想要异步AJAX调用.

注意:同步调用并不意味着您可以放弃不设置回调处理程序.您仍然需要使用回调来处理结果.

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

AJAX客户端服务器通信路径

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

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

同源政策

相同的原始策略基本上意味着如果您的AJAX呼叫来自托管的页面http://www.mysite.com,则无法拨打http://www.othersite.com此处所示的呼叫:

阻止请求的同源策略

您可以通过代理服务解决这个问题.这是您与同一服务器上的脚本交互的地方,该脚本又通过CURL调用与您希望的站点连接.以下说明了此代理方法:

相同的原始代理解决方法

警告请注意,第三方服务器不会将请求视为来自客户端,而是来自服务器.有些服务器对同一个IP不满,因此对服务器进行了多次调用.这可能会阻止您,因此请使用此设置验证相关网站是否正常.

注意:在某些情况下,相同的原始政策不适用,例如Google Chrome扩展程序调用(您必须为每个站点设置权限),某些Greasemonkey调用和Adobe Air.

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

AJAX数据返回

由于它是一个非常受欢迎的选项,我们将使用JSON或(J)ava(S)cript(O)bject(N)orotation来传回数据.JSON基本上看起来像这样:

{
    color: "red",
    value: "#f00"
}
Run Code Online (Sandbox Code Playgroud)

此字符串可以转换为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!');
  }
});
Run Code Online (Sandbox Code Playgroud)

请注意访问返回值的容易程度.另一个流行的选择是从服务器检索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>
Run Code Online (Sandbox Code Playgroud)

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

TODO:处理恶意HTML注入的安全性?

结论

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

  • 原始XMLHTTPRequests也不错.学习$ .ajax或XMLHTTPRequest都同样令人困惑. (2认同)