JavaScript—Ajax基础知识梳理(29)
Ajax用一句话来说就是无须刷新页面即可从服务器取得数据。注意,虽然Ajax翻译过来叫异步JavaScript与XML,但是获得的数据不一定是XML数据,现在服务器端返回的都是JSON格式的文件。
完整的Ajax请求过程
完整的Ajax请求过程
1.创建XMLHttpRequest实例
2.发出HTTP请求
3.接收服务器传回的数据
4.更新网页数据
下面先看一个红宝书上给出的发起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请求过程详解
- 创建XMLHttpRequest实例
从上面的的代码可以看出,创建一个XHR实例方式为:
var xhr = new XMLHttpRequest();
- 发出HTTP请求
实例创建好后,首先需要启动一个HTTP请求,使用XHR的open()方法,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.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.target是XHR对象,另外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类型等等

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript—全栈开发(28)
前言 整个系列,是会采用我的一贯风格,就是不疾不徐,娓娓道来,学习完毕,你可以掌握我提到的全系列的知识,并且得到一个可以直接拷贝的代码模板,并把它用到你的项目中。 完成操练下来,得半小时到一个小时吧。腾出你的时间再来学习。 前端的复杂度很多人是看不起JavaScript开发的。这玩意不就是玩具嘛,一些脚本和标签而已。说这话的时候,他们可能是就翘起二郎腿的,或者抱着膀子的。 然而,前端因为还在快速发展,因此很多东西在变,构造环境的选择比较多,技术种类也不少,很多事情得自己做。因此它其实并不比那么简单的。这篇文章的图,可以窥视到前端复杂的一角了。Modern Frontend Developer in 2018。 我看了不少资料,很多都是讲解这张图中的一个技术,讲解全栈的肯定是有的,但是往往过于复杂。本文试图通过一组文章,把JavaScript的全栈开发做一个全景的展示,力图使用一个案例,全须全尾的贯穿整个系列,便于初学者对技术的急速理解。 大纲所以,文章会包括这些: 使用Vuejs脚手架,快速搭建一个CRD用户界面。会使用vuex管理状态,使用vue-router管理路由。使用Mongo...
- 下一篇
[SOLVED] Caused by: java.awt.HeadlessException when trying to create a...
[SOLVED] Caused by: java.awt.HeadlessException when trying to create a SWING/AWT frame from Spring Boot In Spring Boot, when you try to create a Swing frame from the component that is the entry point of your app, you will get Caused by: java.awt.HeadlessException To solve this, in your Application class in main, instead of: SpringApplication.run (Application.class, args) use SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class); builder.headless(false); ConfigurableA...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16