上一篇单独写的是ajax跨域,这一篇就来详细说一说ajax,ajax是现代web开发中必不可少的一部分内容,非常基础也非常重要,这篇总结一下到目前为止我对ajax的理解。
什么是ajax
ajax是web开发中的一种交互技术,全称为Asynchronous JavaScript And XMLHttpRequest,使用ajax可以实现页面局部更新,每次变化不再需要请求整个页面,之前在我web开发历史的文章中也提到过,从前的web页面每次需要更新时都必须要刷新整个页面,整体体验非常不好。ajax的出现并大量使用在web开发中绝对是颠覆性的变化,它使得开发出优秀的web应用成为现实,从此各种各样的前端技术才得以兴起。时至今日,ajax已经成为web开发中难以或缺的一部分。
ajax的核心自然就是XMLHttpRequest对象了,它存在于所有现代浏览器中(IE5 和 IE6 使用 ActiveXObject),它使得浏览器可以发出HTTP请求与接收HTTP响应。有了这一基础,剩下的就是js交互了,整个过程浏览器就可以处理,而交换数据的文档也不限于xml(现在常用json)。
ajax交互流程
一次ajax交互是浏览器向服务器请求一次数据的过程,整个过程可分为4步:
- 请求发起:在此阶段,由XMLHttpRequest发起一个http请求,GET、POST、PUT、DELETE、UPDATE等等都可以。
- 数据传送:发起请求之后就要传递数据,不同的请求方式传递数据的方式细节不同,但都是浏览器向服务器方向的,因为交互是双方的,数据传递自然很重要。
- 监听状态:整个请求过程结束后浏览器的任务就是等,等待服务器的响应,这个过程不会阻塞用户,只是在后台监听连接状态,这里就体现出异步的优势了。
- 接收响应:服务器处理完数据之后,后返回结果给浏览器,浏览器就可以接收整个请求返回的响应信息,然后本次请求结束。
以上就是一次完整的ajax交互,下面来通过代码展示一下简单的ajax流程。
代码演示
先来看代码
var xhr = new XMLHttpRequest(); xhr.open('GET',url,true); // url 是一个URL xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304){ // 获得 xhr.responseText 为相应数据 } }; xhr.send();
我们来一点点看其中涉及到的方法和相关概念,首先创建了一个XMLHttpRequest对象,然后接下来是一个open方法,第一个参数是请求方法,第二个参数是一个URL,默认情况要求同源(关于同源策略和跨域可以看我上一篇文章),第三个参数指的是是否为异步请求,默认是true可以省略。open方法结束会初始化HTTP请求参数,但是并不发送请求。
做好请求发送准备了,不过现在还不能发送请求。因为请求是异步的,我们无法获知请求的进度和响应状态,XMLHttpRequest给我们提供了一个事件onreadystatechange,我们可以通过监听这个时间来关注这种变化,所以下一步是注册onreadystatechange事件。
先了解一下readyState,当一个XMLHttpRequest初次创建时,这个readyState的值从0开始,直到接收到完整的HTTP响应,这个值增加到4,具体情况如下:
状态 | 名称 | 描述 |
---|---|---|
0 | Uninitialized | 初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置。 |
1 | Open | open()方法已调用,但是 send() 方法未调用。请求还没有被发送。 |
2 | Sent | Send()方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。 |
3 | Receiving | 所有响应头部都已经接收到。响应体开始接收但未完成。 |
4 | Loaded | HTTP 响应已经完全接收。 |
在这里我们只要判断这个值是不是4就可以知道响应是否接收完成了。
另一个要关注的就是status,它指的就是HTTP状态码,这个大家都很熟悉了,只要是200(OK)或304(Not Modified)就是成功的请求(这里也可以关注statusText,它指的是状态码对应的名称,不常用)。此时就可以获取到响应数据了,responseText即为响应体内容(还有一个responseXML,它对请求的响应解析为XML并作为Document对象返回,不常用)。到此,请求准备完全完成。
接下来调用send方法,发送请求,其中如果是POST或PUT请求可以把请求体作为参数传入。整个请求到此就发送完成了。
XMLHttpRequest还有几个这里没涉及到的方法abort,getAllResponseHeaders,getResponseHeader,setRequestHeader,暂时用不到这里不过多介绍了。
对于ie5、6,创建xhr对象要使用new ActiveXObject("Microsoft.XMLHTTP"),不过以后应该没用了。
以上就是原生js实现的ajax,在实际开发中我们几乎永远都不会去写ajax,封装好的ajax库有很多,比较熟悉的jquery中的$.ajax,$get,$post等等。到此,传统的基于XMLHttpRequest 实现的ajax的内容就结束了,不过现在还有一个东西需要认识一下。
fetch
XMLHttpRequest的api上面已经看到了,可以说的上很复杂了,它复杂到我们平时几乎都用不上原生api,于是,一种新的更优雅的解决方案--fetch诞生了。
首先fetch是新东西,先来看浏览器支持率:
可以看出其实不是很乐观,不过不要紧,我们可以使用polyfill来实现,所以可以直接来看fetch的例子:
fetch(url,{ method: 'GET',headers: new Headers({ 'Accept': 'application/json' }) }).then(res=>{ return res.json() }).then(res=>{ console.log(res) }).catch(err=>{ // 处理异常 })
可以看出fetch是基于promise的(关于promise相关内容在这篇文章中提到过),所以可以链式调用,整个过程不难理解,请求结果如果是json还支持直接处理,fetch的api非常实用,适合现代前端开发使用,使用React开发时候通常我们都选fetch作为数据请求工具。
至此,这篇文章内容就结束了,最后还是版权信息:尊重原创,转载分享前请先知悉作者,也欢迎指出错误不足共同交流,更多内容欢迎关注作者博客点击这里