当前位置: 首页 > 工具软件 > XHR > 使用案例 >

Ajax和XHR

范麒
2023-12-01

一、Ajax

1. 介绍

  • Ajax指一种创建交互式网页应用的网页开发技术。
  • 它可以令开发者只向服务器获取数据(而不是HTML文档等资源)

(1)特点

  • 在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并在网页上呈现出来。
  • 由于Ajax请求获取的是数据而不是HTML文档,因此它也节省了网络带宽

(2)原理

  • 其中最核心的依赖是浏览器提供的XMLHttpRequest对象。
  • 简单来说,Ajax就是通过JS发送请求、接收响应,是对浏览器提供的接口进行封装

2. Ajax核心

(1)创建XMLHttpRequest对象

var xhr = new XMLHttpRequest();  

(2)向服务器发送请求

xhr.open(method,url,async);  
send(string);//post请求时才使用字符串参数,否则不用带参数。
  • method:请求的类型;GET 或 POST
  • url:文件在服务器上的位置
  • async:true(异步)或 false(同步)

注意:post请求一定要设置请求头的格式内容

代码实例

xhr.open("POST","test.html",true);  
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");  
xhr.send("fname=Henry&lname=Ford");  //post请求参数放在send里面,即请求体

(3)处理服务端响应

同步处理

xhr.open("GET","info.txt",false);  
xhr.send();  
document.getElementById("myDiv").innerHTML=xhr.responseText; //获取数据直接显示在页面上

异步处理

xhr.onreadystatechange=function()  { 
	if (xhr.readyState===4 &&xhr.status===200)  { 
		document.getElementById("myDiv").innerHTML=xhr.responseText;  
	}
} 
  • xhr.readyState === 4的时候,说明请求结束;
  • 这个时候查看HTTP状态码,如果xhr.status === 200,说明请求成功,已经获取到服务端数据,将数据渲染到页面上。

(4)readyState(XHR状态)

  • readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。
  • readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义
    • 0:未初始化 – 尚未调用.open()方法;
    • 1:启动 – 已经调用.open()方法,但尚未调用.send()方法;
    • 2:发送 – 已经调用.send()方法,但尚未接收到响应;
    • 3:接收 – 已经接收到部分响应数据;
    • 4:完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了;

(5)status(HTTP状态码)

  • HTTP状态码(status)由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。
  • 当状态码为200,即表示请求成功。

3. Ajax请求实现(原理)

  1. 创建XMLHttpRequest对象
  2. 调用send方法发送 Http请求
  3. 监听xhr对象状态变化,JS引擎可以执行其他任务
  4. 等到 readyState 属性值为4,status 属性值为200,就将回调函数放到任务队列中排队执行。
function ajax(url, fnSucc, fnFaild) {
  var xhttp;
 
  // 第一步:创建XMLHttpRequest对象
  if (window.XMLHttpRequest) {
      // 现代浏览器
      xhttp = new XMLHttpRequest();
   } else {
      // IE6等老版本浏览器
      xhttp = new ActiveXObject("Microsoft.XMLHTTP");
	 }

	// 第二步:初始化XMLHttpRequest方法
  xhttp.open('GET', url);
  // 第三步:XMLHttpRequest向服务器发送请求
  xhttp.send();

  // 第四步:处理响应
  xhttp.onreadystatechange = function() {
    if (xhttp.readyState === 4) {
      if (xhttp.status === 200) {
        fnSucc(xhttp.responseText)
      } else {
       if (fnFaild) fnFaild(xhttp.responseText)
      }
    } 
  }
}

4. 总结特性

  1. 就是不跳转不刷新的情况下,在网页后台提交数据,部分更新页面内容,将页面的用户体验提升到接近原生程序的程度。
  2. 第一次下载可能慢一点,但以后操作只与服务器交换关键数据。减轻服务器的负担同时页提高了客户端运行的流程性。
  3. 因为ajax技术是动态加载内容,所以不利于SEO。(单页面应用)

二、XMLHttpRequest(XHR)

1. 简介

  • XMLHttpRequest 一开始只是微软浏览器提供的一个接口,后来各大浏览器纷纷效仿也提供了这个接口。后来W3C对它进行了标准化,提出了 XMLHttpRequest标准
  • XMLHttpRequest 标准又分为Level 1 和Level 2。

2. 版本对比

Level 1的缺点

  • 受同源策略的限制,不能发送跨域请求;
  • 不能发送二进制文件(如图片、视频、音频等),只能发送纯文本数据;
  • 在发送和获取数据的过程中,无法实时获取进度信息,只能判断是否完成;

Level 2 改进

  • 可以发送跨域请求,在服务端允许的情况下;
  • 支持发送和接收二进制数据;
  • 新增formData对象,支持发送表单数据;
  • 发送和获取数据时,可以获取进度信息;
  • 可以设置请求的超时时间;

3. 使用

(1)请求头

设置 request header

  • xhr提供了setRequestHeader来允许我们修改请求header。

获取 response header

  • xhr提供了2个用来获取响应头部的方法:getAllResponseHeadersgetResponseHeader
  • 前者是获取 response 中的所有header 字段,后者只是获取某个指定 header 字段的值。

(2)响应数据

指定xhr.respons类型

  • 有些时候我们希望xhr.response 返回的就是我们想要的数据类型。比如:响应返回的数据是纯JSON字符串,但我们期望最终通过xhr.response 拿到的直接就是一个 js 对象,我们该怎么实现呢?

  • responseType 是xhr level 2 新增的属性,用来指定xhr.response 的数据类型

获取 response 数据

  • xhr 提供了3个属性来获取请求返回的数据,分别是:xhr.response、xhr.responseText、xhr.responseXML

(3)其他

追踪ajax请求的当前状态

  • 用xhr.readyState这个属性即可追踪到。这个属性是只读属性,总共有5种可能值,分别对应xhr不同的不同阶段。每次xhr.readyState的值发生变化时,都会触发xhr.onreadystatechange事件

设置请求的超时时间

  • 如果请求过了很久还没有成功,为了不会白白占用的网络资源,我们一般会主动终止请求。XMLHttpRequest 提供了timeout 属性来允许设置请求的超时时间。
  • 默认值:0,即不设置超时

获取上传、下载的进度

  • 在上传或者下载比较大的文件时,实时显示当前的上传、下载进度是很普遍的产品需求。
  • 我们可以通过 onprogress 事件来实时显示进度,默认情况下这个事件每50ms触发一次。
  • 需要注意的是,上传过程和下载过程触发的是不同对象的 onprogress 事件。
    • 上传触发的是xhr.upload对象的 onprogress事件
    • 下载触发的是xhr对象的onprogress事件

跨域携带cookie

  • 在CORS 标准中做了规定,默认情况下,浏览器在发送跨域请求时,不能发送任何认证信息(cookies)
  • 必须手动设置xhr.withCredentials=true

4. 相关事件

(1)事件触发条件

onreadystatechange

  • 每当xhr.readyState改变时触发

onloadstart

  • 调用xhr.send()方法后立即触发

onprogress

  • xhr.upload.onprogress 在上传阶段(即xhr.send()之后,xhr.readystate=2 之前)触发,每50ms触发一次;
  • xhr.onprogress在下载阶段(即xhr.readystate=3时)触发,每50ms触发一次。

onload

  • 当请求成功完成时触发,此时xhr.readystate = 4

onloadend

  • 当请求结束(包括请求成功和请求失败)时触发

onabort

  • 当调用xhr.abort()后触发

ontimeout:设置超时

  • xhr.timeout 不等于0,由请求开始即onloadstart开始算起,当到达xhr.timeout 所设置时间请求还未结束即onloadend,则触发此事件。

onerror:网络层级别的异常

  • 上传还没有结束,则会先触发xhr.upload.onerror,再触发xhr.onerror;
  • 若发生Network error时,上传已经结束,则只会触发xhr.onerror

(2)事件使用

发生abort/timeout/error异常的处理

  1. 中止请求:一旦发生aborttimeouterror异常,先立即中止当前请求
  2. readystate 置为4,并触发 xhr.onreadystatechange事件
  3. 如果上传阶段还没有结束,则依次触发以下事件:
    • xhr.upload.onprogress
    • xhr.upload.[onabort或ontimeout或onerror]
    • xhr.upload.onloadend
  4. 触发 xhr.onprogress事件
  5. 触发 xhr.[onabort或ontimeout或onerror]事件
  6. 触发xhr.onloadend 事件

在哪个xhr事件中注册请求成功回调?

  • 可以知道若xhr 请求成功,就会触发xhr.onreadystatechangexhr.onload 两个事件。
  • 因为xhr.onreadystatechange 是每次xhr.readyState 变化时都会触发,而不是xhr.readyState=4 时才触发。所以选择 xhr.onload 事件
xhr.onload = function () {
  //如果请求成功
  if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
  	//do successCallback
  }
}
 类似资料: