了解xhr

举报
搞前端的半夏 发表于 2022/05/31 23:40:51 2022/05/31
【摘要】 什么是 XHR?首先什么是XHR?XHR 是 XMLHttpRequest 的首字母缩写。看到这个名字,你会想知道我们为什么了解 Javascript 中的 XML。不要被名称所欺骗,XHR 可用于接收 JSON、HTML、XML 以及纯文本。它是一个内置的浏览器对象,用于客户端和服务器之间的通信。它类似于 Fetch 所做的。XHR 用于 AJAX 编程。对于那些不知道什么是 AJAX ...

什么是 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 发出请求?

  1. 创建构造函数。此构造函数没有参数

    let xhr = new XMLHttpRequest();
    
  2. 在第一步之后,我们通常初始化它

    xhr.open(method, URL, [async, user, password])
    
    • 根据请求的类型,方法可以是“GET”或“POST”
    • URL - 我们必须从哪里获取或发布数据
    • async - 默认情况下为 true,但在必须发出同步请求的情况下,该字段必须显式设置为“false”
    • 用户、密码 - 这些是可选字段,通常在发出任何身份验证请求时使用
  3. 上述方法不调用请求。它只是配置它,但它只在我们发送它时调用

    xhr.send([body])
    

    这里的 body 参数是可选的。通常 GET 请求不需要这个 body 参数,因为我们只是获取信息。另一方面,POST 请求需要这个body 参数,这个参数包含了要发布的信息。

  4. 得到响应

    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 调用我们也需要使用多个属性,

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。