AJAX
AJAX 是开发者的梦想,因为你可以:
在不重新加载页面的情况下更新网页
在页面加载后请求来自服务器的数据
在页面加载后接收来自服务器的数据
在后台向服务器发送数据
HTML 页面
<!DOCTYPE html>
<html>
<body>
<div id="demo">
<h2>让AJAX更改这段文字</h2>
<button type="button" onclick="loadDoc()">更改内容</button>
</div>
</body>
</html>
复制代码
HTML 页面包含一个 <div>
部分和一个 <button>
<div>
部分用于显示来自服务器的信息
<button>
调用一个函数(如果被点击)
该函数从 Web 服务器请求数据并显示它
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
复制代码
上面示例中使用的 "ajax_info.txt" 文件是一个简单的文本文件,内容如下:
<h1>AJAX</h1>
<p>AJAX不是一种编程语言。</p>
<p>AJAX是一种从网页访问Web服务器的技术。</p>
<p>AJAX代表异步JavaScript和XML。</p>
复制代码
什么是 AJAX?
AJAX = 异步 JavaScript 和 XML。
AJAX 不是一种编程语言。
AJAX 只是使用以下组合:
AJAX 是一个具有误导性名称的技术。AJAX 应用程序可能使用 XML 传输数据,但以纯文本或 JSON 文本传输数据同样常见。
AJAX 允许通过在幕后与 Web 服务器交换数据,异步更新 Web 页面。这意味着可以更新 Web 页面的部分,而不必重新加载整个页面。
AJAX 的工作原理
网页中发生事件(页面加载,按钮被点击)
JavaScript 创建 XMLHttpRequest 对象
XMLHttpRequest 对象向 Web 服务器发送请求
服务器处理请求
服务器将响应发送回网页
JavaScript 读取响应
JavaScript 执行适当的操作(例如页面更新)
AJAX - XMLHttpRequest 对象
AJAX 的核心是 XMLHttpRequest 对象。
XMLHttpRequest 对象
所有现代浏览器都支持 XMLHttpRequest 对象。
XMLHttpRequest 对象可用于在幕后与服务器交换数据。这意味着可以更新 Web 页面的部分,而无需重新加载整个页面。
创建 XMLHttpRequest 对象
创建 XMLHttpRequest 对象的语法:
variable = new XMLHttpRequest();
复制代码
示例:
var xhttp = new XMLHttpRequest();
复制代码
上面示例中使用的 "ajax_info.txt" 文件是一个简单的文本文件,内容如下:
<h1>AJAX</h1>
<p>AJAX不是一种编程语言。</p>
<p>AJAX是一种从网页访问Web服务器的技术。</p>
<p>AJAX代表异步JavaScript和XML。</p>
复制代码
跨域访问
出于安全原因,现代浏览器不允许跨域访问。
这意味着网页和它尝试加载的 XML 文件必须位于同一服务器上。
W3Schools 的示例都打开位于 W3Schools 域上的 XML 文件。
如果您想在自己的网页上使用上述示例,则加载的 XML 文件必须位于您自己的服务器上。
XMLHttpRequest 对象方法
XMLHttpRequest 对象属性
AJAX - 发送请求到服务器
XMLHttpRequest 对象用于与服务器交换数据。
发送请求到服务器
要向服务器发送请求,我们使用 XMLHttpRequest 对象的open()
和send()
方法:
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
复制代码
方法描述:
open(method, url, async)
:指定请求类型
method: 请求类型:GET 或 POST
url: 服务器(文件)位置
async: true(异步)或 false(同步)
send()
:将请求发送到服务器(用于 GET)
send(string)
:将请求发送到服务器(用于 POST)
GET 还是 POST?
GET 比 POST 更简单更快,并且在大多数情况下都可以使用。
但是,在以下情况下始终使用 POST 请求:
GET 请求
一个简单的 GET 请求:
示例:
xhttp.open("GET", "demo_get.asp", true);
xhttp.send();
复制代码
在上面的示例中,您可能会得到一个缓存的结果。为了避免这种情况,向 URL 添加一个唯一的 ID:
示例:
xhttp.open("GET", "demo_get.asp?t=" + Math.random(), true);
xhttp.send();
复制代码
如果要使用 GET 方法发送信息,请将信息添加到 URL:
示例:
xhttp.open("GET", "demo_get2.asp?fname=Henry&lname=Ford", true);
xhttp.send();
复制代码
POST 请求
一个简单的 POST 请求:
示例
xhttp.open("POST", "demo_post.asp", true);
xhttp.send();
复制代码
要像 HTML 表单一样发送 POST 数据,请使用setRequestHeader()
添加带有 HTTP 头的请求。在send()
方法中指定要发送的数据:
示例
xhttp.open("POST", "demo_post2.asp", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("fname=Henry&lname=Ford");
复制代码
方法描述:
文件位于服务器上的 URL
open()
方法的 url 参数是指向服务器上文件的地址:
xhttp.open("GET", "ajax_test.asp", true);
复制代码
文件可以是任何类型的文件,如 .txt 和 .xml,或服务器脚本文件,如 .asp 和 .php(它们可以在发送响应之前在服务器上执行操作)。
异步 - True 还是 False?
服务器请求应该异步发送。
open()
方法的 async 参数应设置为 true:
xhttp.open("GET", "ajax_test.asp", true);
复制代码
通过异步发送,JavaScript 无需等待服务器响应,而是可以:
在等待服务器响应时执行其他脚本
在响应准备好后处理响应
onreadystatechange
属性
使用 XMLHttpRequest 对象,您可以定义在请求接收答案时要执行的函数。
该函数在 XMLHttpResponse 对象的onreadystatechange
属性中定义:
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
复制代码
上面示例中使用的 "ajax_info.txt" 文件是一个简单的文本文件,内容如下:
<h1>AJAX
</h1>
<p>AJAX不是一种编程语言。</p>
<p>AJAX是一种从网页访问Web服务器的技术。</p>
<p>AJAX代表异步JavaScript和XML。</p>
复制代码
同步请求
要执行同步请求,将open()
方法中的第三个参数更改为 false:
xhttp.open("GET", "ajax_info.txt", false);
复制代码
有时候async = false
用于快速测试。您还会在旧的 JavaScript 代码中找到同步请求。
由于代码将等待服务器完成,因此无需onreadystatechange
函数:
示例
xhttp.open("GET", "ajax_info.txt", false);
xhttp.send();
document.getElementById("demo").innerHTML = xhttp.responseText;
复制代码
不推荐使用同步 XMLHttpRequest(async = false
),因为 JavaScript 将停止执行,直到服务器响应准备就绪。如果服务器很忙或很慢,应用程序将挂起或停止。
同步 XMLHttpRequest 正在从 Web 标准中删除的过程中,但此过程可能需要很多年。
现代开发工具建议警告使用同步请求,可能在发生时抛出InvalidAccessError
异常。
AJAX - 服务器响应
在 AJAX 中,通过onreadystatechange
属性、readyState
属性、status
属性和statusText
属性来管理 XMLHttpRequest 对象的状态和服务器响应。
onreadystatechange
属性
定义在 readyState
属性更改时要调用的函数。
readyState
属性
保存 XMLHttpRequest 的状态。
0:请求未初始化
1:服务器连接已建立
2:接收请求
3:处理请求
4:请求完成且响应准备就绪
status
属性
200:"OK"403:"Forbidden"404:"Page not found"
获取完整列表请查看 Http Messages Reference
statusText
属性
返回状态文本(例如 "OK" 或 "Not Found")
每次 readyState
更改时都会调用 onreadystatechange
函数。
当 readyState
为 4 且 status
为 200 时,表示响应已准备好。
示例
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
复制代码
上述示例中使用的 "ajax_info.txt" 文件是一个简单的文本文件。
<h1>AJAX</h1>
<p>AJAX 不是一种编程语言。</p>
<p>AJAX 是一种从网页访问 Web 服务器的技术。</p>
<p>AJAX 代表异步 JavaScript 和 XML。</p>
复制代码
onreadystatechange
事件被触发四次(1-4),每次 readyState
更改都会触发一次。
使用回调函数
回调函数是作为参数传递给另一个函数的函数。
示例
loadDoc("url-1", myFunction1);
loadDoc("url-2", myFunction2);
function loadDoc(url, cFunction) {
var xhttp;
xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
cFunction(this);
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
function myFunction1(xhttp) {
// 具体操作在这里
}
function myFunction2(xhttp) {
// 具体操作在这里
}
复制代码
服务器响应属性和方法
responseText
以字符串形式获取响应数据
responseXML
以 XML 数据形式获取响应数据
getAllResponseHeaders()
从服务器资源返回所有标头信息
getResponseHeader()
从服务器响应返回特定的标头信息
示例
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.getAllResponseHeaders();
}
};
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.getResponseHeader("Last-Modified");
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
复制代码
AJAX XML 示例
AJAX 可用于与 XML 文件进行交互式通信。以下是一个展示如何使用 AJAX 从 XML 文件中获取信息的示例:
示例说明
当用户点击上面的 "获取 CD 信息" 按钮时,将执行 loadDoc()
函数。
loadDoc()
函数创建一个 XMLHttpRequest 对象,添加在服务器响应就绪时要执行的函数,并将请求发送到服务器。
当服务器响应就绪时,将构建一个 HTML 表格,从 XML 文件中提取节点(元素),最终使用包含 XML 数据的 HTML 表格更新 "demo" 元素:
LoadXMLDoc()
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open("GET", "cd_catalog.xml", true);
xhttp.send();
}
function myFunction(xml) {
var i;
var xmlDoc = xml.responseXML;
var table = "<tr><th>标题</th><th>艺术家</th></tr>";
var x = xmlDoc.getElementsByTagName("CD");
for (i = 0; i < x.length; i++) {
table += "<tr><td>" +
x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue +
"</td></tr>";
}
document.getElementById("demo").innerHTML = table;
}
复制代码
在上述示例中,通过点击按钮触发 loadDoc()
函数,该函数使用 AJAX 从名为 "cd_catalog.xml" 的 XML 文件中获取信息。当服务器响应就绪时,myFunction()
函数会解析 XML 并构建一个包含 CD 信息的 HTML 表格,最终更新具有 "demo" ID 的元素。
AJAX PHP 示例
AJAX 可用于创建更交互式的应用程序。以下示例演示了如何在用户在输入字段中输入字符时,网页可以与 Web 服务器通信:
示例说明
在上述示例中,当用户在输入字段中键入字符时,将执行名为 "showHint()" 的函数。该函数由 onkeyup
事件触发。
以下是 HTML 代码:
<html>
<head>
<script>
function showHint(str) {
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "gethint.php?q=" + str, true);
xmlhttp.send();
}
}
</script>
</head>
<body>
<p><b>在下面的输入字段中开始输入名字:</b></p>
<form>
姓氏:<input type="text" onkeyup="showHint(this.value)">
</form>
<p>建议:<span id="txtHint"></span></p>
</body>
</html>
复制代码
代码解释
首先,检查输入字段是否为空(str.length == 0
)。如果是,清除 txtHint
占位符的内容并退出函数。
但是,如果输入字段不为空,则执行以下操作:
PHP 文件 - "gethint.php"
PHP 文件检查一个包含名字的数组,并将相应的名字返回给浏览器:
<?php
// 包含名字的数组
$a[] = "Anna";
$a[] = "Brittany";
// ...(省略了其他名字)
// 从 URL 获取 q 参数
$q = $_REQUEST["q"];
$hint = "";
// 如果 $q 与 "" 不同,则从数组中查找所有提示
if ($q !== "") {
$q = strtolower($q);
$len = strlen($q);
foreach ($a as $name) {
if (stristr($q, substr($name, 0, $len))) {
if ($hint === "") {
$hint = $name;
} else {
$hint .= ", $name";
}
}
}
}
// 如果没有找到提示,则输出 "no suggestion",否则输出正确的值
echo $hint === "" ? "no suggestion" : $hint;
?>
复制代码
在上述示例中,当用户在输入字段中输入字符时,通过 AJAX 与服务器通信,并从 PHP 文件中获取相应的建议。建议将在 "txtHint" 元素中显示。
AJAX ASP 示例
AJAX 可用于创建更交互式的应用程序。以下示例演示了如何在用户在输入字段中输入字符时,网页可以与 Web 服务器通信:
示例说明
在上述示例中,当用户在输入字段中键入字符时,将执行名为 "showHint()" 的函数。该函数由 onkeyup
事件触发。
以下是 HTML 代码:
<html>
<head>
<script>
function showHint(str) {
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "gethint.asp?q=" + str, true);
xmlhttp.send();
}
}
</script>
</head>
<body>
<p><b>在下面的输入字段中开始输入名字:</b></p>
<form>
姓氏:<input type="text" onkeyup="showHint(this.value)">
</form>
<p>建议:<span id="txtHint"></span></p>
</body>
</html>
复制代码
代码解释
首先,检查输入字段是否为空(str.length == 0
)。如果是,清除 txtHint
占位符的内容并退出函数。
但是,如果输入字段不为空,则执行以下操作:
ASP 文件 - "gethint.asp"
ASP 文件检查一个包含名字的数组,并将相应的名字返回给浏览器:
<%
response.expires=-1
dim a(30)
' 填充数组
a(1)="Anna"
a(2)="Brittany"
' ...(省略了其他名字)
' 从 URL 获取 q 参数
q=ucase(request.querystring("q"))
' 如果 q 的长度大于 0,则查找数组中的所有提示
if len(q)>0 then
hint=""
for i=1 to 30
if q=ucase(mid(a(i),1,len(q))) then
if hint="" then
hint=a(i)
else
hint=hint & " , " & a(i)
end if
end if
next
end if
' 如果没有找到提示,则输出 "no suggestion",否则输出正确的值
if hint="" then
response.write("no suggestion")
else
response.write(hint)
end if
%>
复制代码
在上述示例中,当用户在输入字段中输入字符时,通过 AJAX 与服务器通信,并从 ASP 文件中获取相应的建议。建议将在 "txtHint" 元素中显示。
AJAX 数据库示例
AJAX 可用于与数据库进行交互式通信。以下示例演示了如何使用 AJAX 从数据库获取信息:
示例
选择一个客户:
<select onchange="showCustomer(this.value)">
<option value="">选择客户:</option>
<option value="ALFKI">ALFKI</option>
<option value="ANATR">ANATR</option>
<option value="ANTON">ANTON</option>
<!-- 其他选项 -->
</select>
<div id="txtHint">客户信息将在此处列出...</div>
复制代码
示例说明 - showCustomer() 函数
当用户在上面的下拉列表中选择一个客户时,将执行名为 "showCustomer()" 的函数。该函数由 "onchange" 事件触发:
function showCustomer(str) {
var xhttp;
if (str == "") {
document.getElementById("txtHint").innerHTML = "";
return;
}
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xhttp.open("GET", "getcustomer.php?q="+str, true);
xhttp.send();
}
复制代码
showCustomer()
函数执行以下操作:
检查是否选择了客户
创建一个 XMLHttpRequest
对象
创建在服务器响应就绪时要执行的函数
将请求发送到服务器上的文件
注意,将一个参数(q
)添加到 URL(带有下拉列表的内容)
AJAX 服务器页面 - "getcustomer.php"
由上面的 JavaScript 调用的服务器上的页面是一个名为 "getcustomer.php" 的 PHP 文件。
"getcustomer.php" 中的源代码针对数据库运行一个查询,并以 HTML 表格的形式返回结果:
<?php
$mysqli = new mysqli("servername", "username", "password", "dbname");
if($mysqli->connect_error) {
exit('Could not connect');
}
$sql = "SELECT customerid, companyname, contactname, address, city, postalcode, country
FROM customers WHERE customerid = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $_GET['q']);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($cid, $cname, $name, $adr, $city, $pcode, $country);
$stmt->fetch();
$stmt->close();
echo "<table>";
echo "<tr>";
echo "<th>CustomerID</th>";
echo "<td>" . $cid . "</td>";
echo "<th>CompanyName</th>";
echo "<td>" . $cname . "</td>";
echo "<th>ContactName</th>";
echo "<td>" . $name . "</td>";
echo "<th>Address</th>";
echo "<td>" . $adr . "</td>";
echo "<th>City</th>";
echo "<td>" . $city . "</td>";
echo "<th>PostalCode</th>";
echo "<td>" . $pcode . "</td>";
echo "<th>Country</th>";
echo "<td>" . $country . "</td>";
echo "</tr>";
echo "</table>";
?>
复制代码
在上述示例中,当用户选择一个客户时,通过 AJAX 与服务器通信,并从数据库中获取相应的客户信息。客户信息将以 HTML 表格的形式显示在具有 "txtHint" ID 的元素中。
在 HTML 表格中显示 XML 数据
此示例循环遍历每个 <CD>
元素,并在 HTML 表格中显示 <ARTIST>
和 <TITLE>
元素的值:
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse:collapse;
}
th, td {
padding: 5px;
}
</style>
</head>
<body>
<button type="button" onclick="loadXMLDoc()">获取我的CD收藏</button>
<br><br>
<table id="demo"></table>
<script>
function loadXMLDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xmlhttp.open("GET", "cd_catalog.xml", true);
xmlhttp.send();
}
function myFunction(xml) {
var i;
var xmlDoc = xml.responseXML;
var table="<tr><th>Artist</th><th>Title</th></tr>";
var x = xmlDoc.getElementsByTagName("CD");
for (i = 0; i <x.length; i++) {
table += "<tr><td>" +
x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
"</td></tr>";
}
document.getElementById("demo").innerHTML = table;
}
</script>
</body>
</html>
复制代码
在 HTML div 元素中显示第一个 CD
此示例使用一个函数来在具有 id="showCD"的 HTML 元素中显示第一个 CD 元素:
<script>
displayCD(0);
function displayCD(i) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this, i);
}
};
xmlhttp.open("GET", "cd_catalog.xml", true);
xmlhttp.send();
}
function myFunction(xml, i) {
var xmlDoc = xml.responseXML;
x = xmlDoc.getElementsByTagName("CD");
document.getElementById("showCD").innerHTML =
"Artist: " +
x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue +
"<br>Title: " +
x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
"<br>Year: " +
x[i].getElementsByTagName("YEAR")[0].childNodes[0].nodeValue;
}
</script>
复制代码
在 CD 之间导航
要在上述示例中在 CD 之间导航,添加next()
和previous()
函数:
<script>
var i = 0;
function next() {
// 显示下一个CD,除非你在最后一个CD上
if (i < x.length-1) {
i++;
displayCD(i);
}
}
function previous() {
// 显示前一个CD,除非你在第一个CD上
if (i > 0) {
i--;
displayCD(i);
}
}
</script>
复制代码
点击 CD 时显示专辑信息
最后一个示例显示了当用户点击 CD 时如何显示专辑信息:
<script>
function displayCD(i) {
document.getElementById("showCD").innerHTML =
"Artist: " +
x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue +
"<br>Title: " +
x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
"<br>Year: " +
x[i].getElementsByTagName("YEAR")[0].childNodes[0].nodeValue;
}
</script>
复制代码
最后
为了方便其他设备和平台的小伙伴观看往期文章:
微信公众号搜索:Let us Coding
,关注后即可获取最新文章推送
看完如果觉得有帮助,欢迎点赞、收藏、关注
评论