Ajax 代表异步 JavaScript + XML,一种在 Web 服务器和浏览器之间进行异步通信的方法。通过使用 Ajax 方法,可以在不切换页面的情况下重写页面内容。在 JavaScript 中,XMLHttpRequest 对象用于使用 Aax 进行异步通信。在这里,我将解释如何使用 Ajax 执行异步通信。
目录
24-1 什么是XMLHttpRequest
24-2 使用XMLHttpRequest进行异步通信
24-3 使用XMLHttpRequest进行同步通信
24-4 Ajax获取文本数据时如何处理乱码
XMLHttpRequest 对象用于使用 Ajax 进行数据通信。使用。创建 XMLHttpRequest 对象后,与服务器通信,一旦接收到数据,使用回调函数处理接收到的数据。本节介绍 XMLHttpRequest 对象的构造函数,以及 XMLHttpRequest 对象提供的方法和属性。
XMLHttpRequest 对象的构造函数
与 Ajax 通信的第一步是创建一个 XMLHttpRequest 对象。使用构造函数创建 XMLHttpRequest 对象。格式如下。
XMLHttpRequest()
创建并初始化一个新的 XMLHttpRequest 对象。
XMLHttpRequest 对象的方法列表
XMLHttpRequest 对象提供的方法包括:
方法 | 説明 |
XMLHttpRequest.abort() | 中止当前通信 |
XMLHttpRequest.getAllResponseHeaders() | 将所有响应标头作为字符串获取 |
XMLHttpRequest.getResponseHeader(标头名称) | 获取指定的响应头作为字符串 |
XMLHttpRequest.open(方法,URL[,异步[,用户名[,密码]]]) | 初始化新的或现有的 HTTP 请求 |
XMLHttpRequest.send(データ) | 向服务器发送 HTTP 请求 |
XMLHttpRequest.setRequestHeader(标头名称,值) | 设置请求标头值 |
XMLHttpRequest.overrideMimeType(MIME类型) | 设置响应的 MIME 类型 |
要使用 Ajax 进行通信,创建一个 XMLHttpRequest 对象,使用 XMLHttpRequest.open 方法设置通信方法,并使用 XMLHttpRequest.send 方法将请求发送到服务器。更详细的步骤在以下几页中解释。
XMLHttpRequest 对象的属性列表
XMLHttpRequest 对象提供的属性包括:
属性 | 解释 |
XMLHttpRequest.onreadystatechange | 事件处理程序之一。 当 readyState 值改变时调用 |
XMLHttpRequest.readyState | XMLHttpRequest 对象的(只读)状态 |
XMLHttpRequest.response | (只读)以 XMLHttpRequest.responseType 设置的格式从服务器接收的数据 |
XMLHttpRequest.responseType | 从服务器接收到的数据格式 |
XMLHttpRequest.responseText | (只读)以文本格式从服务器接收的数据 |
XMLHttpRequest.responseXML | (只读)从服务器接收的 XML 或 HTML 格式的数据 |
XMLHttpRequest.responseURL | (只读)带有响应的 URL(如果目标 URL 被重定向,则重定向 URL) |
XMLHttpRequest.status | (只读)来自服务器的 HTTP 状态代码 |
XMLHttpRequest.statusText | (只读)来自服务器的补充 HTTP 状态代码消息 |
XMLHttpRequest.timeout | 设置请求超时前的毫秒数 |
XMLHttpRequest.ontimeout | 事件处理程序之一。请求超时时调用 |
在异步通信中,对于发送的请求,需要等到所有的数据接收完成后才能处理。XMLHttpRequest.onreadystatechange 属性用于监听数据通信状态,并注册一个回调函数,在数据接收完成时执行。此外,XMLHttpRequest.status 属性用于检查与服务器的通信是否成功。更详细的步骤在以下几页中解释。
可以使用 XMLHttpRequest 对象执行使用 Ajax 的异步通信。这里我们将解释如何创建一个 XMLHttpRequest 对象来通过 Ajax 进行异步通信,向服务器发送请求,并从服务器接收响应。
创建一个 XMLHttpRequest 对象
首先从创建 XMLHttpRequest 对象开始。使用构造函数创建它:
let request = XMLHttpRequest();
已经创建了一个 XMLHttpRequest 对象。
初始化 HTTP 请求(open)
然后使用 XMLHttpRequest 对象的 open 方法来初始化 HTTP 请求。格式如下。
open(方法,URL[,异步[,用户名[,密码]]])
第一个参数指定 HTTP 请求方法。一个字符串值,例如 ‘GET’ 、 ‘POST’ 、 ‘HEAD’ 或 ‘DELETE’ 。主要使用’GET’和’POST’,’GET’用于从服务器获取指定URL的数据或更新数据库),使用’POST’。
第二个参数是一个字符串,指定将请求发送到的 URL。
指定第三次通信是异步还是同步的布尔值。true 用于异步通信,false 用于同步通信。默认值为 true,因此如果省略参数,则为异步通信。
第 4 个和第 5 个参数是字符串,如果需要身份验证,则指定用户名和密码。
这次,我们将使用 GET 方法从服务器异步检索指定 URL 处的文本文件作为示例。像这样写:
let request = new XMLHttpRequest();
request.open('GET', 'https://www.example.com/data.txt', true);
※ 即使省略第三个自变量的 true 也是一样的。
当收到服务器的响应时调用回调函数
在同步通信的情况下,当向服务器发送请求时,它会等待服务器的响应,然后进入下一个过程,但在异步通信的情况下,请求发送到服务器,然后立即进行下一步。对 的处理。
因此,在异步通信的情况下,事件处理程序用于完成从服务器接收响应时发生的事件。事件处理程序在指定事件发生时调用并执行回调函数。
XMLHttpRequest.readyState 属性表示 XMLHttpRequest 对象的状态,可以采用以下值:
0 未初始化 (未调用open方法)
1 Loading (open方法完成,send方法未完成)
2 已加载 (send方法完成,并等待响应)
3 Receiving (接收响应)
4 已完成 (响应接收完成)
例如,如果在创建 XMLHttpRequest 对象后尚未调用 open 方法,则 readyState 属性设置为 0。调用 open 方法时 readyState 属性变为 1。
请看下面的示例。
let request = new XMLHttpRequest();
console.log(request.readyState);
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
console.log(request.readyState);
>> 0
>> 1
实际尝试时,将URL部分重写为常规URL并尝试。这同样适用于以下样品。
readyState 属性在创建 XMLHttpRequest 对象后立即为 0,在执行 open 方法时为 1。
向服务器发送请求并收到服务器响应后,readyState 属性为 4。因此,当readyState属性的值发生变化时,要检查readyState属性的值是否为4,这时候就用到了XMLHttpRequest.onreadystatechange属性。onreadystatechange 属性是一个事件处理程序,当先前注册的回调函数更改 readyState 属性的值时将调用该事件处理程序。
按照以下格式描述onreadystatechange属性回调函数的设置。
XMLHttpRequest.onreadystatechange = 回调函数
让我们使用事件处理程序重写前面的示例。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
console.log(request.readyState);
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
>> 1
open 方法执行时,readyState 属性从 0 变为 1。此更改触发的事件调用先前在 onreadystatechange 属性中设置的回调函数,并将 readyState 属性的值打印到控制台。
这次我想在收到服务器的响应时进行处理,所以当readyState属性的值发生变化并调用回调函数时,我检查了readyState属性的值,如果是4就收到了。描述数据的处理。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
// 描述接收数据的处理
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
检查与服务器的通信是否成功
即使您已经收到来自服务器的响应,您也不知道它是否在响应中收到了来自服务器的所需数据,或者它是否因为未找到服务器或其他原因而收到错误消息。因此,检查 HTTP 状态代码以查看与服务器的通信是否成功。
XMLHttpRequest.status 属性将 HTTP 状态代码的值存储为整数值。主要的 HTTP 状态码是:
200 OK
403 Forbidden
404 Not Found
500 Internarl Server Error
503 Service Unavailable
通信成功返回200。否则会发生错误。(注意send方法发送前先存0)。
收到服务器的响应后,检查 status 属性的值,如果是 200,则说明如何处理收到的数据。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
// 描述接收数据的处理
}
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
检索接收到的数据
在这个示例中,使用 GET 方法从服务器接收数据,因此将接收到的数据存储在变量中以便使用。要检索接收到的数据,请根据数据类型参考以下三个属性。
XMLHttpRequest.responseText
XMLHttpRequest.responseXML
XMLHttpRequest.response
当传入数据是文本时,使用 responseText 属性。当传入数据是表示 XML 或 HTML 的文档对象时,使用 responseXML 属性。response 属性将接收到的数据视为采用 XMLHttpRequest.responseType 属性指定格式的数据。
这次为了获取文本数据,将引用responseText属性获取的数据提取到变量中。(responseXML 属性和 response 属性的使用将在另一页中说明)。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
向服务器发送 HTTP 请求(send)
现在我们已经介绍了如何处理传入数据,我们使用 XMLHttpRequest 对象的 send 方法将请求发送到服务器。格式如下。
send(数据)
该参数指定发送请求时要发送到服务器的数据。使用 GET 方法时指定 null,因为数据通常不会发送到服务器。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
request.send(null);
这样就完成了使用 Ajax 使用 GET 方法从服务器检索文本数据的异步通信代码。
在 HTML 页面中显示从服务器接收到的文本
从服务器接收到文本数据后,您可以将文本数据显示为HTML页面中准备好的div元素或p元素的值,如下所示。
首先,在您的 HTML 页面中编写一个元素来显示您要显示的文本。元素的内容可以为空或显示初始值。
<!DOCTYPE html>
<html lang="zh=CN">
<head></head>
<body>
<p>
点击按钮获取数据。
</p>
<div id="result"></div>
</body>
</html>
“” 是显示接收到的文本的地方。
元素将 id=”result” 设置为稍后检索节点的标识符。
重写的方法是使用DOM获取目标节点,用innerHTML属性重写该值。
let node = document.getElementById("result");
node.innerHTML = request.responseText;
在描述接收数据处理的位置编写此代码。
用控制台测试
现在让我们实际使用 Ajax 通过异步通信获取数据。创建并上传一个名为 data.txt 的文件,在服务器的根目录中输入以下文本。
Hello Yuhua.
Good bye.
接下来,在浏览器中访问任意一个与发送请求的URL相同URL的页面后,打开控制台,执行如下。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
request.send(null);
>> Hello Yuhua.
>> Good bye.
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
request.send(null);
>> Hello Yuhua.
>> Good bye.
网页测试
接下来,当您单击网页上的按钮时,尝试从服务器检索数据并将其显示在网页上的示例。我创建了一个如下所示的 HTML 页面,并将其上传到与要检索的数据相同的域中。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JavaScript TEST</title>
</head>
<body>
<p>
点击按钮获取数据。
</p>
<form>
<input type="button" value="Get Data" onClick="getData()">
</form>
<div id="result"></div>
<script>
function getData(){
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let node = document.getElementById("result");
node.innerHTML = request.responseText;
}
}
}
request.open('GET', 'https://www.flashyonder.com/data.txt', true);
request.send(null);
}
</script>
</body>
</html>
使用浏览器访问您上传上一个 HTML 页面的网页,然后单击页面上显示的按钮。
open 方法的自变量中指定的 URL 表示的文件中描述的内容作为文本数据获取并显示在屏幕上。
我们能够在不切换到新屏幕的情况下在最初显示的网页上显示从服务器接收的数据。
同步通信的步骤
同期通信を行う手順
对于同步通信,我们还从创建 XMLHttpRequest 对象开始。使用构造函数创建它:
let request = XMLHttpRequest();
然后使用 XMLHttpRequest 对象的 open 方法来初始化 HTTP 请求。
这次,我们将使用 GET 方法从服务器同步检索位于指定 URL 的文本文件作为样本。像这样写:
let request = new XMLHttpRequest();
request.open('GET', 'https://www.flashyonder.com/data.txt', false);
请注意,对于同步通信,open 方法的第三个参数必须为 false。
然后使用 XMLHttpRequest 对象的发送方法将请求发送到服务器。
let request = new XMLHttpRequest();
request.open('GET', 'https://www.flashyonder.com/data.txt', false);
request.send(null);
与异步通信不同的是,在同步通信中,执行完send方法后,会停止处理,直到服务器端的所有响应返回完毕。收到所有响应后,我们将进入下一个过程,因此我们将在检查 HTTP 状态码后提取接收到的数据。
let request = new XMLHttpRequest();
request.open('GET', 'https://www.flashyonder.com/data.txt', false);
request.send(null);
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
同步通信现已完成。与肆无忌惮的通信不同的是,描述获取数据过程的位置是在send方法之后描述的,没有使用事件处理程序。这使它更简单,但是在同步通信的情况下,其他处理将停止,直到收到响应。
用控制台测试
现在让我们实际使用同步通信获取数据。创建并上传一个名为 data.txt 的文件,在服务器的根目录中输入以下文本。
Hello Yuhua.
How are you?
接下来,在浏览器中访问任意一个与发送请求的URL相同URL的页面后,打开控制台,执行如下。
let request = new XMLHttpRequest();
request.open('GET', 'https://www.flashyonder.com/data.txt', false);
request.send(null);
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
>> Hello Yuhua.
>> How are you?
open 方法的自变量中指定的 URL 表示的文件中描述的内容作为文本数据获取并输出到控制台。
通常会显示以下警告。
[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
同步通信似乎已被弃用,因为在接收完成之前处理停止。
使用 XMLHttpRequest 对象进行异步通信时,需要注意从服务器获取文本数据时的字符代码。在这里,我们将说明当文本数据以UTF-8以外的字符编码写入时如何消除乱码。
当接收到的文本数据是 UTF-8 以外的字符代码时
通过使用 XMLHttpRequest 对象,您可以向服务器异步发送请求并从服务器接收文本数据。
例如,在服务器端,包含以下文本数据的文件被保存为名称“data_utf8.txt”,使用 UTF-8 作为字符代码。
山东省青岛市
然后从控制台运行该程序,如下所示:
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
}
}
request.open('GET', 'https://www.flashyonder.com/data_utf8.txt', true);
request.send(null);
>> 山东省青岛市
这样我们就能够接收到安装在服务器上的文本文件的数据,并正常输出到控制台。
设置响应的 MIME 类型 (overrideMimeType)
出现乱码是因为响应中使用的字符编码是UTF-8,除非明确设置。如果收到的文本不是 UTF-8,请使用 XMLHttpRequest.overrideMimeType 方法设置响应的 MIME 类型。
overrideMimeType(MIME类型)
在参数中设置 MIME 类型。例如,如果使用Shift_JIS 作为文本格式的字符代码,则说明如下。
let request = new XMLHttpRequest();
request.open('GET', 'https://www.flashyonder.com/data_gb2312.txt', true);
request.overrideMimeType('text/plain; charset=gb2312');
request.send(null);
必须在调用 send 方法之前运行 overrideMimeType 方法。
然后,在如下修改程序后,从控制台执行程序如下,并尝试接收使用 Shift_JIS 作为字符代码的文本数据。
let request = new XMLHttpRequest();
request.onreadystatechange = function(){
if (request.readyState == 4){
if (request.status == 200){
let data = request.responseText;
console.log(data);
}
}
}
request.open('GET', 'https://www.flashyonder.com/data_gb2312.txt', true);
request.overrideMimeType('text/plain; charset=gb2312');
request.send(null);
>> 山东省青岛市
我能够使用 gb2312 作为字符代码接收没有乱码的文本数据。