JavaScript ajax2.0
当你再网络上查询 ajax2.0
的时候,会发现几乎查不到什么东西 ,因为其实他和 XMLHttpRequest Level 2
应该是同义的意思。大家似乎都倾向于查询后者。
在谈到 ajax2.0
之前,不妨先看一下 ajax1.0
有什么缺陷,导致了 2.0
的诞生。
ajax 1.0
- 无法支持文件的上传和读取
- 没有进度反馈信息
- 无法跨域请求数据
而新的 ajax2.0
解决了这些问题,并且带来的新的特性
ajax2.0
假设我们已经创建了一个 xhr
对象
const xhr = new XMLHttpRequest();
// ...
1. 可以设置 timeout
xhr.timeout = 3000;
xhr.ontimeout = () => {
console.log("超时");
};
2. 可以使用 formData
<!-- index.php -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./index.js"></script>
<title>ajax 2.0</title>
</head>
<body>
<form id="form">
<input type="file" name="file" id="file"/>
<input type="submit" id="submit"/>
</form>
</body>
</html>
至于这里为什么要用 index.php
而不用 index.html
,是因为静态文件向 php
文件进行请求的时候会返回 405
// post.php
<?php
$file = $_FILES["file"];
move_uploaded_file($file['tmp_name'], $file['name']); // 移动到当前文件目录下
// index.js
window.onload = () => {
const form = document.querySelector("#form");
const submit = document.querySelector("#submit");
const file = document.querySelector("#file");
const xhr = new XMLHttpRequest();
const formData = new FormData(form);
file.addEventListener("change", function () {
const file = this.files[0];
formData.set("file", file);
});
submit.addEventListener("click", (e) => {
e.preventDefault();
xhr.open("POST", "post.php");
xhr.send(formData);
console.log(formData); // 空
for (let [key, value] of formData) {
console.log(key, value);
}
});
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
};
经过测试,个人认为 formData
有两个非常不合理的地方
formData
和页面上的数据没有做绑定,这意味着使用后还得监听change
事件console.log(formData)
是空,但是let of
循环可以显示出来。
--- 分界线 ---
3. 可以上传文件
上面已经演示过了
4. 可以跨域请求
新的 XHR
可以支持跨域,但是前提是浏览器必须支持 CORS
而且服务端同意跨域,就可以进行跨域请求。
5. 可以读取二进制数据
const xhr = new XMLHttpRequest();
xhr.open("GET", "xxx.png");
xhr.responseType = "blob";
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
const blob = new Blob([xhr.response], { type: 'image/png' });
}
};
这个比较少用到,因为一般获取二进制数据像图像都是给一个 url
地址,然后直接访问这个 url
地址,而不会直接去获取一个二进制数据。
6. 可以获取进度信息
当上传文件的时候
xhr.upload.onprogress = (e) => {
console.log(e);
}
可以看到有 loaded
以及 total
属性,有了这两个就可以显示进度条信息了。
下载文件的时候用的是
xhr.onprogress = (e) => {
console.log(e);
}
总结
ajax2.0
作为大部分网络请求框架的基础,可以了解一下。