JavaScript Ajax
AJAX 是 Asynchronous JavaScript And XML(异步JavaScript和XML)的缩写。AJAX 让网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面。
AJAX 是 Asynchronous JavaScript And XML(异步 JavaScript 和 XML)的缩写。AJAX 让网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面。这使得程序能够更快地回应用户的操作。
AJAX 不是一种编程语言,也不是一种新技术。AJAX 只是使用以下组合:
- 浏览器内置
XMLHttpRequest
对象(从 Web 服务器请求数据) - JavaScript 和 HTML DOM(显示或使用数据)
AJAX 是一个误导性的名称。AJAX 应用程序可能使用 XML 来传输数据,但将数据作为纯文本或 JSON 文本传输也同样常见。
AJAX 允许通过在后台与 Web 服务器交换数据来异步更新网页。这意味着可以更新网页的部分内容,而无需重新加载整个页面。
所有现代浏览器都支持 XMLHttpRequest
对象。
AJAX 的工作原理
下面是一个典型的 AJAX 请求的发生过程:
- 由网页中的事件触发请求(比如页面加载完毕,按钮被点击)
- 由 JavaScript 创建一个 XMLHttpRequest 对象
- XMLHttpRequest 对象向 Web 服务器发送异步请求
- 服务器处理请求
- 服务器向网页发送响应
- 响应被 JavaScript 读取
- 由 JavaScript 执行相应的操作(如页面更新)
创建一个 XMLHttpRequest 对象
所有现代浏览器(Chrome、Firefox、IE、Edge、Safari、Opera)都内置了 XMLHttpRequest
对象。
创建 XMLHttpRequest
对象的语法:
variable = new XMLHttpRequest();
绑定请求完成的回调函数
当 XMLHttpRequest 对象状态发生变化的时候,可以针对不同的状态变化事件绑定相应的处理函数。
为请求完成事件绑定处理函数,处理函数中可以处理请求返回的数据,比如将数据显示到网页等。
xhttp.onload = function () {
// What do do when the response is ready
};
XMLHttpRequest
对象的 onload
绑定请求完成的处理函数。
发送请求
使用 XMLHttpRequest
对象的 open()
和 send()
方法,向服务器发送请求:
xhttp.open("GET", "ajax_info.txt");
xhttp.send();
完整代码框架
// Create an XMLHttpRequest object
const xhttp = new XMLHttpRequest();
// Define a callback function
xhttp.onload = function () {
// Here you can use the Data
};
// Send a request
xhttp.open("GET", "ajax_info.txt");
xhttp.send();
AJAX 请求函数
如果网站中有多个 AJAX 任务,则应创建一个函数来执行 AJAX 请求。该函数有两个参数,一个是服务器的 url, 一个是请求成功后的回调函数。
一个公共的 Ajax 请求函数:
loadDoc("url-1", myFunction1);
loadDoc("url-2", myFunction2);
function loadDoc(url, cFunction) {
const xhttp = new XMLHttpRequest();
xhttp.onload = function () {
cFunction(this);
};
xhttp.open("GET", url);
xhttp.send();
}
function myFunction1(xhttp) {
// action goes here
}
function myFunction2(xhttp) {
// action goes here
}
onreadystatechange 属性
XMLHttpRequest
对象的 readyState
属性保存了请求的状态,onreadystatechange
属性定义了当 readyState
更改时要执行的回调函数。
readyState
有 5 个状态:
0
: 请求还未初始化1
: 与服务器建立了连接2
: 请求接收3
: 处理请求中4
: 请求结束,响应数据返回
status
属性和 statusText
属性保存请求的 HTTP 状态码和状态码消息。
每次 readyState 更改时都会调用 onreadystatechange
函数。
当 readyState
为 4
且状态码为 200
时,响应准备就绪:
function loadDoc() {
const 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");
xhttp.send();
}
向服务器发送请求
要向服务器发送请求,我们使用 XMLHttpRequest
对象的 open()
和 send()
方法:
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
open(method, url, async)
用于定义请求方式,接收 3 个参数:
method
: HTTP 请求方法,比如 GET 或 POSTurl
: 服务器文件 URL 或者 API urlasync
: 是否异步:true (异步), false (同步)
open()
方法的 async
参数应设置为 true
。如果设置为 false
,则可能在请求期间将浏览器挂起,知道请求完成。
send()
方法用于发送请求到服务器,可以接收一个参数,但不是必须的。参数指定要发送到服务器的数据内容。
GET 还是 POST?
GET
比 POST
更简单、更快 ,并且可以在大多数情况下使用。
但是,在以下情况下始终使用 POST 请求:
- 更新服务器上的文件或数据库。
- 向服务器发送大量数据(POST 没有大小限制)。
- 发送用户输入(可能包含未知字符),POST 比 GET 更健壮和安全。
GET 请求
一个简单的 GET
请求:
xhttp.open("GET", "demo_get.asp");
xhttp.send();
在上面的例子中,你可能会得到一个浏览器缓存的结果。为避免这种情况,请向 URL 添加随机参数:
xhttp.open("GET", "demo_get.asp?t=" + Math.random());
xhttp.send();
如果要使用 GET
方法发送信息,请将信息添加到 URL:
xhttp.open("GET", "demo_get2.asp?fname=Henry&lname=Ford");
xhttp.send();
POST 请求
一个简单的 POST
请求:
xhttp.open("POST", "demo_post.asp");
xhttp.send();
要像 HTML 表单一样提交数据,请使用 setRequestHeader()
设置请求头,并在 send()
方法中指定要发送的数据。
xhttp.open("POST", "ajax_test.asp");
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("fname=Henry&lname=Ford");
同步请求
要执行同步请求,请将 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;
不建议使用同步,因为 JavaScript 将停止执行,直到服务器响应准备就绪。如果服务器繁忙或缓慢,应用程序将挂起或停止。
服务器响应属性
responseText
和 responseXML
用于获取服务器相应内容。
responseText 属性
responseText
属性将服务器响应作为字符串返回,您可以直接使用它:
document.getElementById("demo").innerHTML = xhttp.responseText;
responseXML 属性
XMLHttpRequest 对象有一个内置的 XML 解析器,responseXML
属性将服务器响应作为 XML DOM 对象返回。
使用此属性,您可以将响应解析为 XML DOM 对象:
请求文件 cd_catalog.xml 并解析响应:
const xmlDoc = xhttp.responseXML;
const x = xmlDoc.getElementsByTagName("ARTIST");
let txt = "";
for (let i = 0; i < x.length; i++) {
txt += x[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("demo").innerHTML = txt;
xhttp.open("GET", "cd_catalog.xml");
xhttp.send();
服务器响应方法
getResponseHeader()
和 getAllResponseHeaders()
用于获取服务器响应消息头的信息。
getAllResponseHeaders() 方法
getAllResponseHeaders()
方法从服务器响应返回所有消息头信息。
const xhttp = new XMLHttpRequest();
xhttp.onload = function () {
document.getElementById("demo").innerHTML = this.getAllResponseHeaders();
};
xhttp.open("GET", "ajax_info.txt");
xhttp.send();
getResponseHeader() 方法
getResponseHeader()
方法从服务器响应中返回指定的消息头信息。
const xhttp = new XMLHttpRequest();
xhttp.onload = function () {
document.getElementById("demo").innerHTML = this.getResponseHeader("Last-Modified");
};
xhttp.open("GET", "ajax_info.txt");
xhttp.send();
跨域访问
出于安全原因,现代浏览器不允许跨域访问。这意味着网页和它尝试加载的 XML 文件必须位于同一服务器上。
如果您想在您自己的网页之一上使用上面的示例,您加载的 XML 文件必须位于您自己的服务器上。
当然,通过服务器响应消息头的设置,可以实现请求的跨域访问,不过这是另外一个课题,在其他的课程中我们会涉及到。
现代浏览器 Fetch API
现代浏览器可以使用 Fetch API 代替 XMLHttpRequest 对象。
Fetch API 接口允许 Web 浏览器向 Web 服务器发出异步 HTTP 请求。
相对于 XMLHttpRequest 对象,Fetch 可以以更简单的方式执行相同的操作。