AJAX基础知识与简单的操作示例

举报
海拥 发表于 2021/12/30 17:30:32 2021/12/30
【摘要】 🌊 作者主页:海拥🌊 简介:🏆CSDN全栈领域优质创作者、🥇HDZ核心组成员、🥈蝉联C站周榜前十🌊 粉丝福利:粉丝群 每周送6~9本书,不定期送各种小礼品,往期获奖公布@TOC 什么是AJAX?AJAX代表异步的 JavaScript 和 XML。简而言之,就是使用XMLHttpRequest对象与服务器端通信的脚本语言。它可以发送和接收各种格式的信息,包括JSON,XML,HT...

🌊 作者主页:海拥
🌊 简介:🏆CSDN全栈领域优质创作者、🥇HDZ核心组成员、🥈蝉联C站周榜前十
🌊 粉丝福利:粉丝群 每周送6~9本书,不定期送各种小礼品,往期获奖公布

@TOC

什么是AJAX?

AJAX代表异步的 JavaScript 和 XML。简而言之,就是使用XMLHttpRequest对象与服务器端通信的脚本语言。它可以发送和接收各种格式的信息,包括JSON,XML,HTML和文本文件。AJAX最吸引人的特点是其“异步”特性,这意味着它可以与服务器通信,交换数据和更新页面,而不必刷新页面。

AJAX的两个主要功能使您可以执行以下操作:

  • 向服务器发出请求,而无需重新加载页面
  • 从服务器接收和处理数据

步骤1 –如何发出HTTP请求

为了使用JavaScript向服务器发出HTTP请求,您需要一个具有必要功能的对象实例。这就是XMLHttpRequest它的来历。它的前身起源于Internet Explorer,其名称为ActiveX对象XMLHTTP。然后,跟随Mozilla,Safari和其他浏览器,实现了一个XMLHttpRequest对象,该对象支持Microsoft原始ActiveX对象的方法和属性。同时,Microsoft也实现了XMLHttpRequest

// Old compatibility code, no longer needed.
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
    httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}

==注意==:出于说明目的,以上内容是用于创建XMLHttp实例的代码的简化版本。有关更实际的示例,请参见本文的步骤3

提出请求后,您将收到回复。在此阶段,您需要通过设置onreadystatechange对象的属性并在请求更改状态时调用该函数后命名,来告诉XMLHttp请求对象哪个JavaScript函数将处理响应,如下所示:

httpRequest.onreadystatechange = nameOfTheFunction;

请注意,函数名称后没有括号或参数,因为您要分配对该函数的引用,而不是实际调用它。另外,您可以使用JavaScript技术动态定义函数(称为“匿名函数”)来定义将处理响应的操作,而不是给出函数名,如下所示:

httpRequest.onreadystatechange = function(){
    // Process the server response here.
};

接下来,在声明收到响应后会发生什么之后,您需要通过调用HTTP请求对象的open()send()方法来实际发出请求,如下所示:

httpRequest.open('GET', 'http://www.example.org/some.file', true);
httpRequest.send();
  • 调用的第一个参数open()是HTTP请求方法-GET,POST,HEAD或服务器支持的其他方法。保持方法的全大写为HTTP标准,否则某些浏览器(例如Firefox)可能不会处理该请求。有关可能的HTTP请求方法的更多信息,请查看W3C规范
  • 第二个参数是您要将请求发送到的URL。作为一项安全功能,默认情况下,您无法在第三方域上调用URL。请确保在所有页面上使用准确的域名,否则在致电时会出现“权限被拒绝”错误open()。一个常见的陷阱是通过来访问您的网站domain.tld,但尝试使用来调用页面www.domain.tld。如果您确实需要将请求发送到另一个域,请参阅HTTP访问控制(CORS)
  • 可选的第三个参数设置请求是否异步。如果true(默认),则将继续执行JavaScript,并且用户可以在服务器响应尚未到达时与页面进行交互。这是AJAX中的第一个A。

send()如果POST-ing请求,则该方法的参数可以是您要发送到服务器的任何数据。表单数据应以服务器可以解析的格式发送,例如查询字符串:

"name=value&anothername="+encodeURIComponent(myVar)+"&so=on"

或其他格式,例如multipart/form-data,JSON,XML等。

请注意,如果要进行POST数据处理,则可能必须设置请求的MIME类型。例如,在调用send()作为查询字符串发送的表单数据之前,请使用以下命令:

httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

步骤2 –处理服务器响应

发送请求时,您提供了一个JavaScript函数的名称来处理响应:

httpRequest.onreadystatechange = nameOfTheFunction;

此功能应该做什么?首先,该功能需要检查请求的状态。如果状态的值为XMLHttpRequest.DONE(对应于4),则表示已收到完整的服务器响应,可以继续处理它。

if (httpRequest.readyState === XMLHttpRequest.DONE) {
    // Everything is good, the response was received.
} else {
    // Not ready yet.
}

readyState值的完整列表记录在XMLHTTPRequest.readyState中,如下所示:

  • 0(未初始化)或(请求未初始化)
  • 1(正在加载)或(已建立服务器连接)
  • 2(已加载)或(已收到请求)
  • 3(交互式)或(处理请求)
  • 4(完成)或(请求已完成,响应已准备就绪)

接下来,检查HTTP响应的HTTP响应状态代码 。可能的代码在W3C上列出。在以下示例中,我们通过检查200 OK响应代码来区分AJAX调用成功与否。

if (httpRequest.status === 200) {
    // Perfect!
} else {
    // There was a problem with the request.
    // For example, the response may have a 404 (Not Found)
    // or 500 (Internal Server Error) response code.
}

检查请求的状态和响应的HTTP状态代码后,您可以对服务器发送的数据执行任何所需的操作。您可以通过两种方式访问​​该数据:

  • httpRequest.responseText –以文本字符串形式返回服务器响应
  • httpRequest.responseXML–将响应作为XMLDocument可以使用JavaScript DOM函数遍历的对象返回

请注意,仅当您使用了异步请求(open()未指定的第三个参数或将其设置为true)时,以上步骤才有效。如果您使用了 同步请求,则无需指定功能,但是强烈建议不要使用此功能,因为这会带来糟糕的用户体验。

步骤3 – 一个简单的例子

让我们将其与一个简单的HTTP请求放在一起。我们的JavaScript将请求一个HTML文档,test.html其中包含文本“我是测试”。然后,我们将alert()响应的内容。请注意,此示例使用原始JavaScript-不涉及jQuery。此外,HTML,XML和PHP文件应放在同一目录中。

<button id="ajaxButton" type="button">Make a request</button>

<script>
(function() {
  var httpRequest;
  document.getElementById("ajaxButton").addEventListener('click', makeRequest);

  function makeRequest() {
    httpRequest = new XMLHttpRequest();

    if (!httpRequest) {
      alert('Giving up :( Cannot create an XMLHTTP instance');
      return false;
    }
    httpRequest.onreadystatechange = alertContents;
    httpRequest.open('GET', 'test.html');
    httpRequest.send();
  }

  function alertContents() {
    if (httpRequest.readyState === XMLHttpRequest.DONE) {
      if (httpRequest.status === 200) {
        alert(httpRequest.responseText);
      } else {
        alert('There was a problem with the request.');
      }
    }
  }
})();
</script>

在此示例中:

  • 用户单击“发出请求”按钮;
  • 事件处理程序调用该makeRequest()函数;
  • 发出请求,然后(onreadystatechange)执行传递给alertContents();
  • alertContents()检查是否收到响应,然后单击确定,然后检查文件alert()的内容test.html

==注意==:如果要将请求发送到将返回XML而不是静态HTML文件的一段代码,则必须设置响应标头才能在Internet Explorer中工作。如果未设置header Content-Type:application/xml,则IE将在您尝试访问XML元素的行之后引发JavaScript“期望的对象”错误。

==注2==:如果您未设置标头,Cache-Control:no-cache则浏览器将缓存响应并且从不重新提交请求,这给调试带来了挑战。您还可以添加始终不同的GET参数,例如时间戳或随机数

==注3==:如果httpRequest全局使用该变量,则竞争函数调用makeRequest()可能会相互覆盖,从而导致竞争状态。在包含AJAX函数httpRequest
的闭包中声明局部变量可以避免这种情况。

如果发生通信错误(例如服务器关闭),则onreadystatechange在访问响应状态时,方法中将引发异常。为了减轻这个问题,您可以将if...then语句包装在中try...catch

function alertContents() {
  try {
    if (httpRequest.readyState === XMLHttpRequest.DONE) {
      if (httpRequest.status === 200) {
        alert(httpRequest.responseText);
      } else {
        alert('There was a problem with the request.');
      }
    }
  }
  catch( e ) {
    alert('Caught Exception: ' + e.description);
  }
}

步骤4 –使用XML响应

在上一个示例中,在收到对HTTP请求的响应之后,我们使用了请求对象的responseTextproperty,该属性包含test.html文件的内容。现在让我们尝试一下该responseXML属性。

首先,让我们创建一个有效的XML文档,稍后我们将请求它。文档(test.xml)包含以下内容:

<?xml version="1.0" ?>
<root>
    I'm a test.
</root>

在脚本中,我们只需要将请求行更改为:

...
onclick="makeRequest('test.xml')">
...

然后在中alertContents(),我们需要将行替换为alert(httpRequest.responseText;:

var xmldoc = httpRequest.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);

该代码采用由XMLDocument给定的对象,responseXML并使用DOM方法访问XML文档中包含的某些数据。你可以看到test.xml 和更新的测试脚本。

步骤5 –处理数据

最后,让我们将一些数据发送到服务器并接收响应。这次,我们的JavaScript将请求一个动态页面test.php,该页面将接收我们发送的数据并返回一个"computed" string-“Hello, [user data]!” -我们将其alert().

首先,我们将在HTML中添加一个文本框,以便用户输入其名称:

<label>Your name:
  <input type="text" id="ajaxTextbox" />
</label>
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
  Make a request
</span>

我们还将在事件处理程序中添加一行,以从文本框中获取用户数据,并将其makeRequest()与服务器端脚本的URL一起发送至函数:

  document.getElementById("ajaxButton").onclick = function() {
      var userName = document.getElementById("ajaxTextbox").value;
      makeRequest('test.php',userName);
  };

我们需要进行修改makeRequest()以接受用户数据并将其传递给服务器。我们将请求方法从更改GETPOST,并将我们的数据作为参数包含在对的调用中httpRequest.send()

 function makeRequest(url, userName) {

    ...

    httpRequest.onreadystatechange = alertContents;
    httpRequest.open('POST', url);
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    httpRequest.send('userName=' + encodeURIComponent(userName));
  }

该函数alertContents()可以按照第3步中的相同方式编写,以警告我们计算出的字符串(如果这一切都是服务器返回的)。但是,假设服务器将返回计算的字符串和原始用户数据。因此,如果我们的用户在文本框中键入“ Jane”,则服务器的响应将如下所示:

{"userData":"Jane","computedString":"Hi, Jane!"}

要在中使用此数据alertContents(),我们不能只responseText向发出警报,我们必须对其进行解析并向警报发出computedString我们想要的属性:

function alertContents() {
  if (httpRequest.readyState === XMLHttpRequest.DONE) {
    if (httpRequest.status === 200) {
      var response = JSON.parse(httpRequest.responseText);
      alert(response.computedString);
    } else {
      alert('There was a problem with the request.');
    }
  }
}

test.php文件应包含以下内容:

$name = (isset($_POST['userName'])) ? $_POST['userName'] : 'no name';
$computedString = "Hi, " . $name . "!";
$array = ['userName' => $name, 'computedString' => $computedString];
echo json_encode($array);

有关DOM方法的更多信息,请确保检查文档对象模型(DOM)。

简单的定时XHR示例

接下来是另一个简单的示例-在这里,我们通过XHR加载文本文件,假定其结构如下:

TIME: 312.05
TIME: 312.07
TIME: 312.10
TIME: 312.12
TIME: 312.14
TIME: 312.15

加载文本文件后,我们split()将项目放入每个换行符的数组中(\n基本上是每个换行符在文本文件中的位置),然后将完整的时间戳列表和最后一个时间戳打印到页面上。

使用setInterval()呼叫每5秒重复一次。这样的想法是,某种服务器端脚本将使用新的时间戳不断更新文本文件,而我们的XHR代码将用于报告客户端的最新时间戳。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>XHR log time</title>
    <style>

    </style>
  </head>
  <body>
    <p id="writeData" class="data">Off-Line</p>
    <p id="lastStamp">No Data yet</p>

    <script>

    const fullData = document.getElementById('writeData');
    const lastData = document.getElementById('lastStamp');

    function fetchData() {
      console.log('Fetching updated data.');
      let xhr = new XMLHttpRequest();
      xhr.open("GET", "time-log.txt", true);
      xhr.onload = function() {
        updateDisplay(xhr.response);
      }
      xhr.send();
    }

    function updateDisplay(text) {
      fullData.textContent = text;

      let timeArray = text.split('\n');

      // included because some file systems always include a blank line at the end of text files.
      if(timeArray[timeArray.length-1] === '') {
        timeArray.pop();
      }

      lastData.textContent = timeArray[timeArray.length-1];
    }

    setInterval(fetchData, 5000);
    </script>
  </body>
</html>

聪明的人已经关注作者了
后面我还会持续更新类似免费好玩的H5小游戏、Java小游戏、好玩、实用的项目和软件等等

最后,不要忘了❤或📑

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。