一、Ajax是什么
Ajax是一种异步请求数据的web开发技术,在不需要重新整体刷新(局部刷新)页面的情况下, 通过异步请求加载后台数据,并在网页上呈现出来。常见运用场景
- 表单验证是否登入成功
- 百度搜索下拉框提示
- 快递单号查询
由于AJAX请求获取的是数据而不是HTML文档,可以减少网络数据的传输量,提高用户体验。
二、Ajax原理
Ajax请求数据依赖浏览器提供的XMLHttpRequest对象,可以使浏览器可以发出HTTP请求与接收HTTP响应,而浏览器接着做其他事情,等收到XHR返回来的数据再渲染页面。
三、Ajax基础
XMLHttpRequest有两种执行模式:同步(synchronous)和异步(asynchronous)。
要发送请求,需要 3 个步骤:
1. 创建 XMLHttpRequest:
let xhr = new XMLHttpRequest();// 兼容性处理if(window.XMLHttpRequest){xhr = new XMLHttpRequest();}else{xhr = new ActiveXObject('IE.XMLHttp')}
2. 初始化配置请求
xhr.open(method, URL, [async, user, password])
主要参数:
method—— HTTP 方法。通常是"GET"或"POST"。URL—— 要请求的 URL,通常是一个字符串,也可以是 URL 对象。async—— 如果显式地设置为false,那么请求将会以同步的方式处理,我们稍后会讲到它。user,password—— HTTP 基本身份验证(如果需要的话)的登录名和密码。open调用与其名称相反,不会建立连接。它仅配置请求,而网络活动仅以send调用开启
3. 发送请求
xhr.send([body])
这个方法会建立连接,并将请求发送到服务器。可选参数 body 包含了 request body。
GET没有 request body。POST使用body将数据发送到服务器。
4. 监听xhr事件以获取响应。
这三个事件是最常用的:
load—— 当请求完成(即使 HTTP 状态为 400 或 500 等),并且响应已完全下载。error—— 当无法发出请求,例如网络中断或者无效的 URL。progress—— 在下载响应期间定期触发,报告已经下载了多少。
error,abort,timeout和load事件是互斥的。其中只有一种可能发生。
旧版
const xhr = new XMLHttpRequest()xhr.onreadystatechange = () => {if (xhr.readystate == 4) {if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText)} else {alert("Request was unsuccessful: " + xhr.status)}}}xhr.open("get", "example.php", true)xhr.send(null)
新版:load事件帮助我们节省了readstatechange事件,不必在XHR对象实例上监听readyState属性的变化
// 1. 创建一个 new XMLHttpRequest 对象let xhr = new XMLHttpRequest();// 2. 配置它:从 URL /article/.../load GET-requestxhr.open('GET', '/article/xmlhttprequest/example/load');// 3. 通过网络发送请求xhr.send();// 4. 当接收到响应后,将调用此函数xhr.onload = function() {if (xhr.status != 200) { // 分析响应的 HTTP 状态alert(`Error ${xhr.status}: ${xhr.statusText}`); // 例如 404: Not Found} else { // 显示结果alert(`Done, got ${xhr.response.length} bytes`); // response 是服务器响应}};xhr.onprogress = function(event) {if (event.lengthComputable) {alert(`Received ${event.loaded} of ${event.total} bytes`);} else {alert(`Received ${event.loaded} bytes`); // 没有 Content-Length}};xhr.onerror = function() {alert("Request failed");};
四、XMLHttpRequest对象
方法
open():准备启动一个AJAX请求;setRequestHeader():设置请求头部信息;send():发送AJAX请求;getResponseHeader(): 获得响应头部信息;getAllResponseHeader():获得一个包含所有头部信息的长字符串;abort():取消异步请求;onreadystatechange:当XML实例的readyState属性变化时,就会触发该事件的发生;
属性
readyState:表示“请求”/“响应”过程的当前活动阶段status:响应的HTTP状态;statusText:HTTP状态的说明;responseText/response:包含响应主体返回文本;responseType:设置响应格式withCredentials: 是否将 cookie 和 HTTP 授权发送到其他域,默认false
响应类型
使用 xhr.responseType 属性来设置响应格式:
""(默认)—— 响应格式为字符串,"text"—— 响应格式为字符串,"arraybuffer"—— 响应格式为ArrayBuffer"blob"—— 响应格式为Blob"document"—— 响应格式为 XML document(可以使用 XPath 和其他 XML 方法),"json"—— 响应格式为 JSON(自动解析)。
readyState
XMLHttpRequest 的状态(state)会随着它的处理进度变化而变化。可以通过 xhr.readyState 来了解当前状态。
UNSENT = 0; // 初始状态OPENED = 1; // open 被调用HEADERS_RECEIVED = 2; // 接收到 response headerLOADING = 3; // 响应正在被加载(接收到一个数据包)DONE = 4; // 请求完成
XMLHttpRequest 对象以 0 → 1 → 2 → 3 → … → 3 → 4 的顺序在它们之间转变。
每当通过网络接收到一个数据包,就会重复一次状态 3。
可以使用 readystatechange 事件来跟踪它们:
xhr.onreadystatechange = function() {if (xhr.readyState == 3) {// 加载中}if (xhr.readyState == 4) {// 请求完成}};
在非常老的代码中找到 readystatechange 这样的事件监听器。如今,它已被 load/error/progress 事件处理程序所替代。
GET请求和POST请求
GET请求
- GET请求用于获取数据,将查询参数追加到URL的末尾,令服务器解析。
- 查询字符串中每个参数的名和值都必须使用
encodeURIComponent()进行编码(这是因为URL中有些字符会引起歧义,例如“&”)。POST请求
POST请求用于向服务器发送应该被保存的数据,包括表单数据或JSON字符串,使用send(data)。那么这些数据应该放在何处呢?毕竟,我们的 ```javascript // 表单FormData let formData = new FormData([form]); // 创建一个对象,可以选择从
// JSON字符串 let xhr = new XMLHttpRequest(); let json = JSON.stringify({ name: “John”, surname: “Smith” });
xhr.open(“POST”, ‘/submit’) // 有了它,很多服务端框架都能自动解码 JSON xhr.setRequestHeader(‘Content-type’, ‘application/json; charset=utf-8’); xhr.send(json);
注意以下两点:1. `.send()`方法的参数是**不可为空**的,**GET请求**,也需要使用`send(null)`方法;1. 两种向服务器发送数据的方式:**表单提交**以及**发送POST请求**;<a name="019eff4f"></a>## HTTP-header`XMLHttpRequest` 允许发送自定义 header,并且可以从响应中读取 header。<br />HTTP-header 有三种方法:<a name="0AsYJ"></a>### `setRequestHeader(name, value)````javascriptxhr.setRequestHeader('Content-Type', 'application/json');
Header 的限制
- 一些 header 是由浏览器专门管理的,为了用户安全和请求的正确性,
XMLHttpRequest不允许更改它们例如Referer** 和 **Host。- 不能移除 header
XMLHttpRequest的另一个特点是不能撤销setRequestHeader。一旦设置了 header,就无法撤销了。其他调用会向 header 中添加信息,但不会覆盖它。
xhr.setRequestHeader('X-Auth', '123');xhr.setRequestHeader('X-Auth', '456');// header 将是:// X-Auth: 123, 456
getResponseHeader(name)
获取具有给定 name 的 header(Set-Cookie 和 Set-Cookie2 除外)。
getAllResponseHeaders()
返回除 Set-Cookie 和 Set-Cookie2 外的所有 response header
取消异步请求
可以随时终止请求。调用 xhr.abort() 即可:
xhr.abort(); // 终止请求
它会触发 abort 事件,且 xhr.status 变为 0。
进度事件
progress 事件:加载进度条效果
仅在下载阶段触发
onprogress事件处理程序会接收到一个event对象,其有3个属性
lengthComputable:表示进度信息是否可用的布尔值;position:表示目前接收的字节数;totalSize:表示根据Content-Length响应头部确定的预期字节数;
注意,需要在const xhr = new XMLHttpRequest()xhr.onload = () => {if ((xhr.status >= 200 && xhr.status <300) || xhr.status == 304) {alert(xhr.responseText)} else {alert("Something wrong!")}}// 加载进度条xhr.onprogress = function(event) {const divStatus = document.getElementById("status")if (event.lengthComputable) {divStatus.innerHTML = `Received ${event.postion} of ${event.totalSize} bytes`}}xhr.open("get", "example.php", true)xhr.send(null)
.open()方法前调用onprogress事件处理程序。
**upload事件:用于跟踪上传事件
类似于
xhr**对象,**它会生成事件
xhr.upload 仅在上传时触发它们:
loadstart—— 上传开始。progress—— 上传期间定期触发。abort—— 上传中止。error—— 非 HTTP 错误。load—— 上传成功完成。timeout—— 上传超时(如果设置了timeout属性)。loadend—— 上传完成,无论成功还是 error。``javascript xhr.upload.onprogress = function(event) { alert(Uploaded ${event.loaded} of ${event.total} bytes`); };
xhr.upload.onload = function() {
alert(Upload finished successfully.);
};
xhr.upload.onerror = function() {
alert(Error during the upload: ${xhr.status});
};
```
