了解xhr
什么是 XHR?
首先什么是XHR?XHR 是 XMLHttpRequest 的首字母缩写。看到这个名字,你会想知道我们为什么了解 Javascript 中的 XML。
不要被名称所欺骗,XHR 可用于接收 JSON、HTML、XML 以及纯文本。它是一个内置的浏览器对象,用于客户端和服务器之间的通信。它类似于 Fetch 所做的。
XHR 用于 AJAX 编程。对于那些不知道什么是 AJAX 的人来说,AJAX 是异步 Javascript 和 XML。基本上,通过这种技术,客户端和服务器可以异步通信。
为什么要使用 XHR?
所以你可能想知道为什么我们需要 XHR 以及为什么我们需要进行异步编程?
异步编程
异步编程有助于提高系统效率并防止长时间等待。例如,有一个请求需要从服务器获取数据。这个操作非常耗时,如果我们使用同步编程,浏览器会等待数据被获取,然后才会执行其他任务。这将导致代码阻塞。为了避免这种情况,我们使用异步编程。
XHR 事件
以下事件被广泛使用:
-
status - 返回 HTTP 状态码
-
statusText - 返回 HTTP 状态消息
-
load – 当请求完成并且响应完全下载时
-
error- 当请求未完成时,例如。网络中断或 URL 无效
-
process – 在下载响应时间隔触发,通知用户已下载了多少响应
-
timeout - 指定超时,如果事件在给定时间内未完成,它会被取消并触发超时事件(以毫秒为单位)
xhr.timeout = 5000;
-
abort - 这会触发 abort 事件,并且 xhr.status 变为 0
xhr.abort()
XHR 的用途
- 更新网页而不重新加载页面
- 从服务器请求数据(页面加载后)
- 从服务器接收数据(页面加载后)
- 在后台发送数据到服务器,没有代码阻塞
如何使用 XHR 发出请求?
-
创建构造函数。此构造函数没有参数
let xhr = new XMLHttpRequest();
-
在第一步之后,我们通常初始化它
xhr.open(method, URL, [async, user, password])
- 根据请求的类型,方法可以是“GET”或“POST”
- URL - 我们必须从哪里获取或发布数据
- async - 默认情况下为 true,但在必须发出同步请求的情况下,该字段必须显式设置为“false”
- 用户、密码 - 这些是可选字段,通常在发出任何身份验证请求时使用
-
上述方法不调用请求。它只是配置它,但它只在我们发送它时调用
xhr.send([body])
这里的 body 参数是可选的。通常 GET 请求不需要这个 body 参数,因为我们只是获取信息。另一方面,POST 请求需要这个body 参数,这个参数包含了要发布的信息。
-
得到响应
xhr.onload = function() { alert("Loaded"); }; xhr.onerror = function() { // only triggers if the request couldn't be made at all alert("Network Error"); }; xhr.onprogress = function(event) { // event.loaded - how many bytes downloaded // event.total - total number of bytes alert(`Received ${event.loaded} of ${event.total}`); };
程序代码
使用 XHR
function App() {
const [data, setData] = useState([]);
useEffect(() => {
let xhr = new XMLHttpRequest();
xhr.open("GET", "https://jsonplaceholder.typicode.com/todos");
xhr.send();
xhr.onload = function () {
if (xhr.status !== 200) {
// console logs the error if request is unsuccessful
console.log(`Error ${xhr.status}: ${xhr.statusText}`);
} else {
// sets the data only if we get a successful response
// we need to parse the data since the data is obtained in the string type
setData(JSON.parse(xhr.response));
}
};
xhr.onerror = function() {
alert("Request failed");
};
}, []);
return (
<div className="App">
{data?.map((obj, index) => (
<div key={index}>{obj.title}</div>
))}
</div>
);
}
上面的代码从 Todos API 获取数据,并且只在屏幕上显示每个 todo 的标题。正如您在上面的代码中看到的,我们必须解析数据以获取 JSON 格式的数据。这是因为响应默认为字符串类型。为了避免解析,可以使用一个名为“responseType”的属性。初始化构造函数后,我们可以添加以下语句
复制
xhr.responseType = 'json';
还有各种其他数据类型,例如“arraybuffer”、“blob”、“document”,但这些不是很常用。你可以在这里阅读更多关于它的信息
使用 fetch 重写上面的代码
function App() {
const [data, setData] = useState([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/todos")
.then((response) => response.json())
.then((json) => setData(json))
.catch((err) => console.log(err));
}, []);
return (
<div className="App">
{data.map((obj, index) => (
<div key={index}>{obj.title}</div>
))}
</div>
);
}
如果您将上面的代码与 XHR 代码进行比较,您会发现我们需要设置两个侦听器来处理成功和错误情况以及对 open() 和 send() 的调用。但是与 XHR 相比,获取语法非常简单且更易于理解。
为什么在现代使用 XHR?
- 需要用 XMLHttpRequest 支持现有脚本。
- 需要支持旧浏览器
- 与 Fetch 相比,XHR 具有更多功能 - onprogress、abort 和 timeout
概括
XHR 与 fetch 类似,可用于客户端和服务器之间的通信。尽管语法是这样的,即使是简单的 API 调用我们也需要使用多个属性,
- 点赞
- 收藏
- 关注作者
评论(0)