首页 > 其他分享 >http request-01-XMLHttpRequest XHR 简单介绍

http request-01-XMLHttpRequest XHR 简单介绍

时间:2024-08-17 16:05:57浏览次数:10  
标签:status 01 XMLHttpRequest 请求 XHR request xhr console

http 请求系列

http request-01-XMLHttpRequest XHR 简单介绍

http request-01-XMLHttpRequest XHR 标准

Ajax 详解-01-AJAX(Asynchronous JavaScript and XML)入门介绍

Ajax XHR 的替代方案-fetch

Ajax XHR 的替代方案-fetch 标准

Ajax 的替代方案-axios.js

http 请求-04-promise 对象 + async/await

XHR 的官方学习资料 给出网址

以下是一些官方学习 XMLHttpRequest (XHR) 的资源网址:

  1. MDN Web Docs - XMLHttpRequest

    • MDN XMLHttpRequest Documentation
    • 这是最权威和详细的 XHR 文档,提供了关于如何使用 XMLHttpRequest 的全面介绍,包括属性、方法、事件和示例代码。
  2. WhatWG - XMLHttpRequest Standard

    • WhatWG XMLHttpRequest Standard
    • WhatWG 的标准文档详细描述了 XMLHttpRequest 的规范和实现细节,是了解其正式标准的良好资源。
  3. W3C - XMLHttpRequest Level 2 Specification

    • W3C XMLHttpRequest Level 2
    • W3C 的规范文档提供了 XMLHttpRequest Level 2 的详细描述,包括新增的功能和改进。

这些资源将帮助你深入理解 XMLHttpRequest 的功能、用法和规范。

XHR 是什么?

XMLHttpRequest(XHR)是一个用于在客户端和服务器之间进行异步 HTTP 请求的 API,广泛用于动态更新网页内容,而无需重新加载整个页面。

尽管它最初是为了处理 XML 数据而设计的,但它现在支持多种数据格式,并已成为 Web 开发中重要的工具。

1. 基本概念

XMLHttpRequest 提供了在客户端(如浏览器)与服务器之间进行异步通信的能力,使得网页可以在不重新加载页面的情况下更新内容。

它的主要用途包括动态加载数据、提交表单以及与服务器进行实时交互。

2. 核心方法和属性

2.1 创建请求

const xhr = new XMLHttpRequest();

2.2 配置请求

  • open(method, url, async, user, password): 初始化请求。
    • method: HTTP 方法(如 GETPOST)。
    • url: 请求的 URL。
    • async: 是否异步(truefalse)。
    • userpassword: 可选的身份验证信息。
xhr.open('GET', 'https://example.com/data', true);

2.3 发送请求

  • send(body): 发送请求。body 参数用于发送数据(对于 GET 请求,通常为空)。
xhr.send();

2.4 事件处理

  • onload: 请求成功完成时触发。
  • onerror: 请求失败时触发。
  • onprogress: 请求进度更新时触发(适用于进度监控)。
  • onabort: 请求被取消时触发。
  • onreadystatechange: 请求状态改变时触发。
xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log(xhr.responseText);
  } else {
    console.error('Request failed with status:', xhr.status);
  }
};

xhr.onerror = function() {
  console.error('Request error');
};

2.5 重要属性

  • readyState: 请求的当前状态(0: UNSENT, 1: OPENED, 2: HEADERS_RECEIVED, 3: LOADING, 4: DONE)。
  • status: HTTP 响应状态码(如 200、404、500)。
  • statusText: 响应状态文本。
  • responseText: 响应的文本内容。
  • responseXML: 响应的 XML 文档(如果 Content-Typeapplication/xmltext/xml)。
  • response: 根据响应类型(如 ArrayBufferBlob)返回的响应数据。

3. 使用示例

3.1 简单 GET 请求

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);
xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Response:', xhr.responseText);
  } else {
    console.error('Error:', xhr.status, xhr.statusText);
  }
};
xhr.send();

3.2 POST 请求

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://jsonplaceholder.typicode.com/posts', true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.onload = function() {
  if (xhr.status === 201) {
    console.log('Created:', xhr.responseText);
  } else {
    console.error('Error:', xhr.status, xhr.statusText);
  }
};
const data = JSON.stringify({ title: 'foo', body: 'bar', userId: 1 });
xhr.send(data);

3.3 进度监控

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);
xhr.onprogress = function(event) {
  if (event.lengthComputable) {
    const percentComplete = (event.loaded / event.total) * 100;
    console.log('Progress:', percentComplete.toFixed(2) + '%');
  }
};
xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Response:', xhr.responseText);
  } else {
    console.error('Error:', xhr.status, xhr.statusText);
  }
};
xhr.send();

4. 优缺点

4.1 优点

  • 广泛支持: 兼容大多数浏览器,包括较早版本。
  • 灵活性: 支持多种 HTTP 方法和请求体格式。
  • 进度监控: 能够监控请求的进度和状态变化。

4.2 缺点

  • 复杂性: 处理异步操作和错误处理可能比较复杂,特别是嵌套的回调函数(“回调地狱”)。
  • 现代替代品: 比如 fetch API 提供了更简洁的语法和更强大的功能,例如流处理和更好的错误处理。

5. 现代替代

XMLHttpRequest 的一些功能和用途已经被更现代的 fetch API 所取代。fetch 提供了更简洁的语法、支持 Promise 和流处理,使得异步操作和错误处理更为直观。

XHR 为什么需要?解决了什么问题

XMLHttpRequest (XHR) 是一种用于在浏览器和服务器之间进行异步通信的 API。它在 Web 开发中解决了多个关键问题,特别是在用户体验和动态网页更新方面。

以下是 XMLHttpRequest 需要的原因及其解决的问题:

1. 页面异步更新

问题

  • 传统的网页请求: 每次需要从服务器获取新数据或提交数据时,整个页面必须重新加载。这种方式会导致用户体验不流畅,页面刷新较慢。

解决方案

  • XHR 的异步请求: 允许网页在不重新加载整个页面的情况下,从服务器获取数据并更新部分页面内容。这使得网页可以实现局部更新,而不是每次都刷新整个页面,从而提高了用户体验和响应速度。

2. 提高用户体验

问题

  • 页面停顿: 在传统的同步请求中,用户必须等待整个请求和响应过程完成,这可能导致页面停顿或冻结。

解决方案

  • 异步处理: XMLHttpRequest 通过异步处理请求,允许浏览器在发出请求时继续执行其他操作,不会阻塞用户界面的交互。这样,用户可以继续与网页进行交互,而不会受到请求等待的影响。

3. 动态内容加载

问题

  • 静态网页内容: 在没有异步请求的情况下,网页内容通常是静态的,所有内容都在页面加载时获取。

解决方案

  • 动态内容加载: 通过 XMLHttpRequest,网页可以在运行时动态加载数据,并根据需要更新内容。比如,用户滚动到页面底部时自动加载更多数据(如无限滚动),或者基于用户输入实时更新搜索结果。

4. 后台数据处理

问题

  • 用户交互时的数据提交: 用户在填写表单时,数据提交通常会导致页面重新加载,影响用户体验。

解决方案

  • 表单提交: 使用 XMLHttpRequest 可以在不刷新页面的情况下提交表单数据。这使得用户可以在不离开当前页面的情况下完成数据提交和处理。

5. 局部更新和请求管理

问题

  • 整体更新难度: 如果需要对部分页面内容进行更新,传统方法通常需要复杂的页面重载和数据处理。

解决方案

  • 局部更新: XMLHttpRequest 允许通过指定的 URL 和请求方法,只更新页面的某一部分内容。这简化了局部更新的实现,并减少了对服务器的负担。

6. 进度监控

问题

  • 缺乏反馈: 在传统请求中,用户无法获得请求进度的信息(如正在下载的进度)。

解决方案

  • 进度事件: XMLHttpRequest 提供了 onprogress 事件,使得开发者可以实时监控请求的进度,并向用户提供反馈,例如显示下载进度条。

7. 与其他技术的兼容性

问题

  • 旧版浏览器支持: 在 fetch API 出现之前,许多旧版浏览器不支持现代的 HTTP 请求 API。

解决方案

  • 兼容性: XMLHttpRequest 作为较早的标准,得到了广泛的浏览器支持,包括旧版浏览器。这使得它在需要兼容旧版浏览器的应用中仍然非常重要。

XHR 的适用场景,优缺点

XMLHttpRequest(XHR)在 Web 开发中有一些特定的适用场景,以及它的优点和缺点。

以下是一些实际应用场景和它们的优缺点,用更接地气的方式来解释:

适用场景

  1. 动态内容更新

    • 场景: 当你希望在用户与网页交互时,动态更新页面的一部分内容,例如加载评论、文章或产品列表,而不需要重新加载整个页面。
    • 例子: 社交媒体平台上的帖子加载,电商网站上的产品筛选。
  2. 异步表单提交

    • 场景: 当用户填写表单并提交数据时,你希望在后台处理这些数据,而不刷新整个页面。
    • 例子: 用户在评论框中输入内容并提交,数据直接上传到服务器,页面不会重载。
  3. 局部数据刷新

    • 场景: 需要刷新网页的某个部分的数据,而不是整个页面。例如,实时更新价格或天气信息。
    • 例子: 监控仪表板上更新服务器状态,新闻网站上实时更新新闻头条。
  4. 进度反馈

    • 场景: 需要监控和展示文件上传或下载的进度,让用户知道操作的进展。
    • 例子: 文件上传表单,下载大文件时显示进度条。
  5. 旧版浏览器兼容

    • 场景: 如果你的应用需要支持旧版浏览器,它可能不支持现代的 fetch API,但支持 XMLHttpRequest
    • 例子: 针对使用老旧设备或浏览器的用户群体的应用。

优点

  1. 广泛支持

    • 优点: 几乎所有的浏览器都支持 XMLHttpRequest,包括许多旧版浏览器。
    • 实际感受: 你不需要担心用户的浏览器是否支持,因为它几乎能在所有环境中工作。
  2. 灵活性

    • 优点: 支持多种 HTTP 方法(GET、POST、PUT、DELETE 等),并且能够处理不同格式的响应数据。
    • 实际感受: 可以用来做各种各样的请求,比如从服务器获取 JSON 数据或发送表单数据。
  3. 进度监控

    • 优点: 提供 onprogress 事件,可以监控请求的进度。
    • 实际感受: 你可以给用户提供下载或上传的实时进度,提升用户体验。

缺点

  1. 复杂性

    • 缺点: 处理异步请求和响应可能会很复杂,尤其是在嵌套回调函数(“回调地狱”)的情况下。
    • 实际感受: 编写代码时可能会变得混乱,不容易维护。
  2. 没有内建的 Promise 支持

    • 缺点: 不像 fetch API,XMLHttpRequest 默认不支持 Promise,处理异步操作时需要使用回调函数。
    • 实际感受: 需要额外的工作来处理异步操作,代码可能不够简洁。
  3. 较少的功能扩展

    • 缺点: 与现代 API 比如 fetch 相比,XMLHttpRequest 在流处理和功能扩展方面有所限制。
    • 实际感受: 如果需要更高级的功能,比如流式处理大文件,XMLHttpRequest 可能无法满足需求。

XHR 的使用最佳实践

使用 XMLHttpRequest (XHR) 时,遵循一些最佳实践可以帮助你写出更高效、可靠和可维护的代码。以下是一些实际的最佳实践:

1. 使用异步请求

  • 实践: 总是将 XMLHttpRequestasync 参数设置为 true,以便异步处理请求。
  • 理由: 异步请求不会阻塞用户界面,提高了用户体验。
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data', true);
xhr.send();

2. 处理请求状态变化

  • 实践: 使用 onreadystatechange 事件来处理请求的不同状态。确保检查 readyStatestatus 属性来确定请求是否成功完成。
  • 理由: readyState 提供了请求的当前状态,status 表示 HTTP 响应状态码,帮助你正确处理响应或错误。
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data', true);
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) { // DONE
    if (xhr.status === 200) {
      console.log('Response:', xhr.responseText);
    } else {
      console.error('Error:', xhr.status, xhr.statusText);
    }
  }
};
xhr.send();

3. 设置适当的请求头

  • 实践: 根据需要设置请求头(例如 Content-Type)。如果你发送 JSON 数据,确保设置 Content-Typeapplication/json
  • 理由: 请求头可以影响服务器如何处理请求体,确保请求和响应数据格式的正确性。
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://example.com/data', true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
const data = JSON.stringify({ key: 'value' });
xhr.send(data);

4. 处理错误和超时

  • 实践: 使用 onerror 事件处理网络错误,使用 ontimeout 处理超时情况。设置超时时间以防止请求挂起过久。
  • 理由: 错误处理可以提供更好的用户反馈和恢复机制,而超时处理可以避免长时间等待无响应的请求。
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data', true);
xhr.timeout = 5000; // 设置超时时间为 5000 毫秒

xhr.ontimeout = function() {
  console.error('Request timed out');
};

xhr.onerror = function() {
  console.error('Request error');
};

xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('Response:', xhr.responseText);
  }
};

xhr.send();

5. 监控进度

  • 实践: 使用 onprogress 事件来监控请求的进度,尤其是处理大文件上传或下载时。
  • 理由: 进度反馈可以改善用户体验,让用户了解操作的进展。
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/largefile', true);
xhr.onprogress = function(event) {
  if (event.lengthComputable) {
    const percentComplete = (event.loaded / event.total) * 100;
    console.log('Progress:', percentComplete.toFixed(2) + '%');
  }
};
xhr.onload = function() {
  if (xhr.status === 200) {
    console.log('File downloaded successfully');
  }
};
xhr.send();

6. 避免回调地狱

  • 实践: 使用清晰的回调结构或考虑使用 Promises(如果需要兼容性,可以用 Promise 封装 XHR)。虽然 XHR 本身不支持 Promise,但你可以创建自己的封装。
  • 理由: 清晰的回调结构或使用 Promise 可以提高代码的可读性和可维护性。
function fetchData(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onload = function() {
      if (xhr.status === 200) {
        resolve(xhr.responseText);
      } else {
        reject(new Error(`Request failed with status ${xhr.status}`));
      }
    };
    xhr.onerror = function() {
      reject(new Error('Network error'));
    };
    xhr.send();
  });
}

// 使用
fetchData('https://example.com/data')
  .then(response => console.log('Response:', response))
  .catch(error => console.error('Error:', error));

7. 处理不同数据格式

  • 实践: 根据服务器响应的 Content-Type 处理数据。例如,如果响应是 JSON 格式,则调用 responseText 并使用 JSON.parse 解析。
  • 理由: 正确处理不同的数据格式确保数据解析的准确性。
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data', true);
xhr.onload = function() {
  if (xhr.status === 200) {
    const contentType = xhr.getResponseHeader('Content-Type');
    if (contentType.includes('application/json')) {
      const data = JSON.parse(xhr.responseText);
      console.log('JSON data:', data);
    } else {
      console.log('Response:', xhr.responseText);
    }
  }
};
xhr.send();

8. 保持代码简洁

  • 实践: 尽量保持 XHR 请求代码简洁,避免过多的嵌套和复杂逻辑。封装常用逻辑为函数可以提高可重用性。
  • 理由: 简洁的代码更易于维护和理解。
function createRequest(method, url, callback) {
  const xhr = new XMLHttpRequest();
  xhr.open(method, url, true);
  xhr.onload = function() {
    if (xhr.status >= 200 && xhr.status < 300) {
      callback(null, xhr.responseText);
    } else {
      callback(new Error(`Request failed with status ${xhr.status}`));
    }
  };
  xhr.onerror = function() {
    callback(new Error('Network error'));
  };
  xhr.send();
}

// 使用
createRequest('GET', 'https://example.com/data', (error, response) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Response:', response);
  }
});

总结

遵循这些最佳实践可以帮助你在使用 XMLHttpRequest 时编写更高效、可靠和易于维护的代码。

虽然 fetch API 提供了更现代的接口,但了解和掌握 XMLHttpRequest 仍然在许多情况下很重要,尤其是在处理兼容性问题时。

标签:status,01,XMLHttpRequest,请求,XHR,request,xhr,console
From: https://www.cnblogs.com/houbbBlogs/p/18364518

相关文章

  • 洛谷P5663 [CSP-J2019] 加工零件
    传送门:P5663[CSP-J2019]加工零件这是一篇写于2024.8.17的做题记录,祝稻米朋友们节日快乐。废话还是少说一点比较好qwq题目意思:(一个很抽象的东西)说白了其实就是给你一张无向图,然后有p次询问,每次询问给你一个v和L,问你从1号点到v号点有没有长度为L的边。注意......
  • 信息学奥赛一本通编程启蒙题解(3011~3015)
    前言Hello大家好,我是文宇.正文3011#include<iostream>usingnamespacestd;intmain(){ inta,b,s; a=880; b=500; s=a*b; cout<<s; return0;}注:没有输入的都可以直接输出.3012#include<iostream>usingnamespacestd;inta,b,t;intmain(){ a=10;b=20......
  • 01、Vue3+TypeScript基础,创建第一个页面
    1、main.js代码如下://引入createApp用于创建Vue实例import{createApp}from'vue'//引入App.vue根组件importAppfrom'./App.vue'constapp=createApp(App);//App.vue的根元素id为appapp.mount('#app')2、App.vue代码如下:<template><div......
  • 【保研/考研之争】——01
        前段时间过的比较浑浑噩噩,基本在靠刷手机度过,美其名曰扩大自己的眼界、增长自己的知识面来麻痹自己,然而实际上陷入在其中意识不到危机的来临,现在每天让自己少看些手机,尽量将每天看手机的时间保持在1~2h内,将电子设备等放在自己比较费劲才能取到的地方,通过电脑学习,同时写......
  • 读软件开发安全之道:概念、设计与实施01基础
    1. 基础1.1. 实现软件安全既需要运用逻辑,又是一项艺术1.1.1. 一项仰赖直觉来做出判断的艺术1.1.2. 需要践行者对当代数字系统有所掌1.1.3. 需要他们对人与系统之间的交互有所体悟1.2. 需要准确地思考一下何谓安全1.2.1. 安全定义的主观性颇强,因此厘清安全......
  • 【408DS算法题】016基础-倒序输出单链表的结点值
    Index题目分析实现总结题目给定单链表的头结点,倒序输出单链表的结点值。分析实现要倒序输出链表结点值,首先可以想到的是先将链表的结点值存储到数组中,然后利用数组随机访问的特性进行倒序输出。如果考虑其它思路的话,还可以使用栈来代替数组——将链表元素依次......
  • day01
    markdown学习标题三级标题四级标题123456488465151气温气温气温恶趣味企鹅请问请问驱蚊器请问驱蚊器字体撒大声地阿德啊打实打实大阿达的引用骆大帅分割线图片超链接点击跳转到骆大帅博客地址列表阿达asdasadasdadasddadsaddasdas表格......
  • 鸿蒙交互事件开发01——点击/拖拽/触摸事件
     如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。1  概  述  事件是人机交互的基础,鸿蒙开发中,事件分为两大类:a)通用事件;b)手势事件。......
  • 【题解】「NOIP2012」疫情控制
    https://www.luogu.com.cn/problem/P1084这道题难在贪心的思路,实现比较简单可以直接看代码。首先二分。现在转化为判定问题。可以用倍增求出每个军队最上面能到哪。结论1:我们一定不会把在除了根节点以外的军队往下移动。否则肯定不优。所以我们把能走到根节点的先存在一起......
  • 01背包问题
    有 NN 件物品和一个容量是 VV 的背包。每件物品只能使用一次。第 ii 件物品的体积是 vivi,价值是 wiwi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。输入格式第一行两个整数,N,VN,V,用空格隔开,分别表示物品数量和背包容积......