资讯专栏INFORMATION COLUMN

Ajax基础知识梳理

XBaron / 3238人阅读

摘要:当客户端收到以上信息后,首先要判断状态码来确认响应是否成功,状态码在之间表示请求成功,同时代表请求资源未被修改,可使用浏览器本地缓存。校验状态码输出响应的文本打印其他状态码发送异步请求如果将方法的第三个参数设为,即为异步请求。

Ajax用一句话来说就是无须刷新页面即可从服务器取得数据。注意,虽然Ajax翻译过来叫异步JavaScriptXML,但是获得的数据不一定是XML数据,现在服务器端返回的都是JSON格式的文件。

完整的Ajax请求过程

完整的Ajax请求过程

创建XMLHttpRequest实例

发出HTTP请求

接收服务器传回的数据

更新网页数据

下面先看一个红宝书上给出的发起Ajax请求的例子,API的用法在后面章节给出。

var xhr = new XMLHttpRequest();  // 创建XMLHttpRequest实例

xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){   // 判断请求响应过程阶段,4 阶段代表已接收到数据
    if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {  // 校验HTTP状态码
      console.log(xhr.responseText);   // 输出响应的文本
    } else {
      console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码
    }
  }
};

xhr.open("get", "example.txt", true); // 初始化xhr实例,或者说启动请求
xhr.send(null);  // 设置HTTP请求携带参数,null为不带参数
Ajax请求过程详解 1. 创建XMLHttpRequest实例

从上面的的代码可以看出,创建一个XHR实例方式为:

var xhr = new XMLHttpRequest();
2. 发出HTTP请求

实例创建好后,首先需要启动一个HTTP请求,使用XHRopen()方法,open方法接受三个参数

XMLHttpRequest.open(method, url, isAsync)
// 例如
xhr.open("get", "http://www.baidu.com", true)

第一个参数为http请求使用方法,如("get","post"等),第二是参数是请求的url, 第三个参数代表是否异步发送请求(可选)。调用open()方法后会启动一个http请求,但它不会立即发送请求,处于待命状态。需要注意的是:请求的url必须要跟请求源域(origin)同域,也就是说协议、域名、端口号要一致,跨域请求要使用别的方法。接着调用send()方法就会发出这个http请求。

xhr.open("get", "http://www.baidu.com", true)
xhr.send(null)

send()方法接受一个参数,为http请求发送的数据(通常用于"post"方法),如果为null,表示不发送数据。至此,一个异步的http请求就发送到了服务器。

3. 接收服务器传回的数据 3.1 发送同步请求

如果将open方法的第三个参数设为false,即为同步请求,当收到服务器的响应后,相应的数据会自动填充到XHR对象的属性中,主要包括以下四个:

responseText:作为响应主体被返回的文本。

responseXML: 响应返回的XML文档,能接收到的前提是,响应的Content-Type字段的值为
text/xml或者application/xml

status: HTTP状态码。

statusText: HTTP状态码说明。

当客户端收到以上信息后,首先要判断HTTP状态码来确认响应是否成功,状态码在200-300之间表示请求成功,同时304代表请求资源未被修改,可使用浏览器本地缓存。如果成功就可以获取响应报文主体中的数据了。

xhr.open("get", "http://www.baidu.com", false)
xhr.send(null)

if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {  // 校验HTTP状态码
  console.log(xhr.responseText);   // 输出响应的文本
} else {
  console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码
}
3.2 发送异步请求

如果将open方法的第三个参数设为true,即为异步请求。那么就需要一个事件来通知程序异步请求的结果是否返回。XHR对象中的readyState属性,表示请求/响应整个过程所处的阶段,它有五个值分为对应五个阶段:

0:未初始化。未调用open()方法。

1:启动。已经调用open()方法,但未调用send()方法。

2:发送。已调用send()方法,但未收到响应。

3: 接收。已经接收到部分响应数据。

4:完成。已经接受到全部响应数据。

readyState的值每变化一次,都会触发一次readStatechange事件,我们定义一个事件处理函数onreadStatechange(),并监听readyState == 4状态,就可以得知响应数据已全部收到,并进行下一步操作。那么就是文章开头给出的代码:

var xhr = new XMLHttpRequest();  // 创建XMLHttpRequest实例

xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){   // 判断请求响应过程阶段,4 阶段代表已接收到数据
    if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {  // 校验HTTP状态码
      console.log(xhr.responseText);   // 输出响应的文本
    } else {
      console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码
    }
  }
};

xhr.open("get", "example.txt", true); // 初始化xhr实例,或者说启动请求
xhr.send(null);  // 设置HTTP请求携带参数,null为不带参数
补充XHR中三个有用的事件 timeout事件

当超出了设置时间还未收到响应,就会触发timeout事件,进而调用ontimeout事件处理程序。同时timeout也是XHR的一个属性,用于设置这个时间阈值。下面是用法:

xhr.ontimeout = function() {
  alert("timeout!")
}

xhr.open("get", "http://www.baidu.com", true)
xhr.timeout = 1000 // 时间阈值设为1秒
xhr.send(null)
load事件

load事件用于简化对readState值的判断,响应数据全部接收完毕后(也就是readState == 4)会触发load事件,使用onload事件处理函数进行后续操作,onload会接收一个event对象,它的target属性等于XHR对象,当然我们在定义这个事件处理函数时也可以不传入这个参数,来看下面的用法:

var xhr = new XMLHttpRequest()
xhr.onload = function () {
  if(xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {
    console.log(xhr.responseText);   // 输出响应的文本
  } else {
    console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码
  }
}
xhr.open("get", "http://www.baidu.com", true)
xhr.send(null)

这样就不用去关心readyState值的变化情况了。当然如果想在特定readyState值上做一些逻辑处理,还是要用之前的方法。

progress事件

这个是很有用的一个事件,progress事件会在浏览器接收数据期间周期触发,代表整个请求过程的进度,它的事件处理程序onprogress接收一个event对象,event.targetXHR对象,另外event还有三个属性:

lengthComputable:Boolean值,进度信息是否可用。

position:已经接收到的字节数。

totalSize:总共要接收的字节数,被定义在响应报文的Content-Length字段中。

如果响应报文中有Content-Length字段,那么我们就可以计算当前时刻响应数据的加载进度了,这也是之前看到的一个面试题。看下面的代码:

xhr.onprogress = function(event) {
  if(event.lengthComputable) {
    console.log(`Received: ${(event.position/event.totalSize).toFixed(4)*100}%`);
  }
}

其他还有很多有用的API,如FormData表单序列化,overrideMimeType()重写XHR响应的MIME类型等等,后面慢慢更新。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96211.html

相关文章

  • 跨域知识梳理

    摘要:摘自阮一峰博客延伸阅读不涉及跨域跨源资源分享为标准兼容性参考优点提供安全的跨域数据传输,且不限于请求。跨域资源共享阿里云技术文档跨域资源共享详解阮一峰 参考:维基百科 - Root domainhttps://en.wikipedia.org/wiki...浏览器同源政策及其规避方法 - 阮一峰http://www.ruanyifeng.com/blo...window.name 跨域...

    SwordFly 评论0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...

    enali 评论0 收藏0
  • 前端开发收集 - 收藏集 - 掘金

    摘要:责编现代化的方式开发一个图片上传工具前端掘金对于图片上传,大家一定不陌生。之深入事件机制前端掘金事件绑定的方式原生的事件绑定方式有几种想必有很多朋友说种目前,在本人目前的研究中,只有两种半两种半还有半种的且听我道来。 Ajax 与数据传输 - 前端 - 掘金背景 在没有ajax之前,前端与后台传数据都是靠表单传输,使用表单的方法传输数据有一个比较大的问题就是每次提交数据都会刷新页面,用...

    ygyooo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<