AJAX基础知识与简单的操作示例
🌊 作者主页:海拥
🌊 简介:🏆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请求的响应之后,我们使用了请求对象的responseText
property,该属性包含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()
以接受用户数据并将其传递给服务器。我们将请求方法从更改GET
为POST
,并将我们的数据作为参数包含在对的调用中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小游戏、好玩、实用的项目和软件等等
最后,不要忘了❤或📑
- 点赞
- 收藏
- 关注作者
评论(0)