JavaScript之原生Ajax
Ajax在前端开发中有着举足轻重的地位,关于Ajax的使用和注意事项一直是一个重要的话题,借此机会,本文希望对Ajax做一个全面的总结,彻底揭开Ajax的神秘面纱。
一、什么是Ajax
二、原生的Ajax
2.1 XMLHttpRequest对象
XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。所以XMLHttpRequest对象是Ajax技术的核心所在。
2.2 实现流程
创建XMLHttpRequest对象→打开请求地址,初始化数据→发送请求数据→监听回调函数状态→收到服务器返回的应答结果。
下面用具体的代码进行解释(以简单的ajax中get请求为例):
1 <script type="text/javascript">
2 // 第一步:创建一个xhr对象(你可以称呼它为小黄人)
3 let xhr = null
4 if (window.XMLHttpRequest) {
5 //Firefox、 Opera、 IE7 和其它浏览器使用本地 JavaScript 对象
6 xhr = new XMLHttpRequest();
7 } else {
8 //IE 5 和 IE 6 使用 ActiveX 控件
9 var request = new ActiveXObject("Microsoft.XMLHTTP");
10 }
11 // 第二步:打开请求地址,初始化数据
12 xhr.open("GET", "需要请求的地址", true);
13 // 第三步:发送请求数据
14 xhr.send()
15 // 第四步:监听回调函数状态
16 xhr.onreadystatechange = function(){
17 if(xhr.readyState === 4 && xhr.status === 200){
18 // 收到服务器返回的应答结果
19 console.log(xhr.responseText)
20 }
21 }
22 </script>
2.3 原生写法中的注意点
(1)open()的第三个参数中使用了true,该参数规定请求是否异步处理,默认是异步。true表示脚本会在send()方法之后继续执行,而不等待来自服务器的响应。
(2)关于readyState
值 | 状态 | 描述 |
0 | UNSENT | 代理被创建,但尚未调用 open() 方法。 |
1 | OPENED | open()方法已经被调用。 |
2 | HEADERS_RECEIVED | send()方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING | 下载中; responseText 属性已经包含部分数据。 |
4 | DONE | 下载操作已完成。 |
(3)关于status 由服务器返回的 HTTP 状态代码,200 表示成功,而 404 表示 "Not Found" 错误。当 readyState 小于 3 的时候读取这一属性会导致一个异常。(后面会有http状态码的详细解读)
2.4 GET和POST区别
作为Ajax最常用的两种数据提交方式,GET和POST有着自己的特点和适用场景,正确区分GET和POST的不同并根据实际需要进行选用在开发中十分重要!
先上一张GET 和 POST的比较图,从这张图中可以看出两者之间的差别:
作为Ajax最常用的两种数据提交方式,GET和POST有着自己的特点和适用场景,正确区分GET和POST的不同并根据实际需要进行选用在开发中十分重要,简单但是关键!
先上一张GET 和 POST的比较图,从这张图中可以看出两者之间的差别:
GET | POST | |
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交) |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded或multipart/form-data。为二进制数据使用多重编码 |
历史 | 参数保留在浏览器历史中 | 参数不会保存在浏览器历史中 |
对数据长度限制 | URL的最大长度是2048个字符 | 无限制 |
对数据类型的限制 | 只允许ASCII字符 | 没有限制,也允许为二进制数据 |
安全性 | 安全性相对较差,因为所发送的数据是URL的一部分 | POST比GET相对更为安全,因为参数不会被保存在浏览器历史或Web服务器日志中 |
可见性 | 数据在URL中对所有人都是可见的 | 数据不会显示在URL中 |
从表格中拎出关键点:1、传递数据的方式不同:get是直接把请求数据放在url的后面,是可见的;post的请求数据不会显示在url中,是不可见的。2、数据长度和数据类型的差异:get数据的长度是有限制的,而且数据类型只允许ASCII字符;post在这两方面都没有限制。3、安全性的差异:get不安全;post相对更安全。
由此得出的两者的使用场景:get使用比较简单,适用于两个页面之间而非敏感数据的简单传值;post使用较为安全,适用于向服务器发送密码、token等敏感数据。
2.5 原生Ajax的其它使用方法
(1)ajax之get请求
1 <script type="text/javascript">
2 let xhr = null
3 if (window.XMLHttpRequest) {
4 xhr = new XMLHttpRequest();
5 } else {
6 xhr = new ActiveXObject("Microsoft.XMLHTTP");
7 }
8 // 常规写法
9 xhr.open("GET", "http://0.0.0.0/example", true);
10 // 如果存在请求参数,则直接在url后面拼接即可,我们称请求参数为querystring
11 // xhr.open("GET", "http://0.0.0.0/example?name=张三&age=18", true);
12 // 因为get请求存在缓存问题,我们一般会在后面拼接一个时间戳或随机数
13 // xhr.open("GET", `http://0.0.0.0/example?name=张三&age=18&time=${new Date().getTime}`, true);
14 xhr.send()
15 xhr.onreadystatechange = function(){
16 if(xhr.readyState === 4 && xhr.status === 200){
17 console.log(xhr.responseText)
18 }
19 }
20 </script>
(2)ajax之post请求
1 <script type="text/javascript">
2 let xhr = null
3 if (window.XMLHttpRequest) {
4 var request = new XMLHttpRequest();
5 } else {
6 var request = new ActiveXObject("Microsoft.XMLHTTP");
7 }
8 // 常规写法
9 xhr.open("POST", "http://0.0.0.0/example", true);
10 //设置Content-Type
11 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
12 // 携带请求数据数据,如果没有则为空
13 // xhr.send("name=张三&age=23")
14 xhr.onreadystatechange = function(){
15 if(xhr.readyState === 4 && xhr.status === 200){
16 console.log(xhr.responseText)
17 }
18 }
19 </script>
三、再议HTTP状态码
前面提到的200、404只是状态码中最常见的两个,当浏览器访问一个网页时,浏览者的浏览器会向网页所在的服务器发出请求。当浏览器接收并显示网页前,网页所在的服务器会返回一个包含http状态码的信息头(server header)用以响应浏览器的请求。
常见的http状态码大致有以下一些:
- 200:请求成功,一般用于get和post请求
- 301:永久重定向
- 302:临时重定向
- 304:请求资源未修改,使用缓存
- 401:未授权
- 403:禁止访问
- 404:客户端请求失败
- 414:Request-URI 太长
- 500:内部服务错误,无法完成请求
- 505:服务器不支持请求的HTTP协议版本,无法完成处理
四、不可忽视的http头文件
http请求中的一个重要关注点就是请求头和响应头的内容,从这两个头文件中可以看出很多东西,当我们用发送一个ajax请求的时候,如果没有达到预期的效果,那么就需要打开浏览器的调试工具,从NetWork中找到相应的ajax请求,再通过查看请求头和响应头的信息,大体会知道这次请求的结果是怎么样的,结合响应的主体内容,可以很快找到问题。所以学会看http的头文件信息是前端开发中必须掌握的一个技能,下面就来看看具体的头文件信息。
首先随便上一张百度中的完成一个搜索结果的http请求,可以从图中的右侧清楚看到请求头和响应头的内容,包括了很多个字段信息,这些字段信息就是我们需要掌握的知识点,下面挑出其中的重点字段进行分析。
4.1 请求信息头
- Accept:客户端支持的数据类型
- Accept-Charset:客户端采用的编码
- Accept-Encoding:客户端支持的数据压缩格式
- Accept-Language:客户端的语言环境
- Cookie:客服端的cookie
- Host:请求的服务器地址
- Connection:客户端与服务连接类型
- If-Modified-Since:上一次请求资源的缓存时间,与Last-Modified对应
- If-None-Match:客户段缓存数据的唯一标识,与Etag对应
- Referer: 发起请求的源地址
4.2 响应头信息
- content-encoding:响应数据的压缩格式
- content-length:响应数据的长度
- content-language:语言环境
- content-type:响应数据的类型
- Date:消息发送的时间
- Age:经过的时间
- Etag:被请求变量的实体值,用于判断请求的资源是否发生变化
- Expiress:缓存的过期时间
- Last-Modified:在服务器端最后被修改的时间
- server:服务器的型号
4.3 两者都可能出现的消息
(1)Pragma:是否缓存(http1.0提出)
(2)Cache-Control: 是否缓存(http1.1提出)
4.4 跟缓存相关的字段
(1) 强制缓存 expire 和 cache-control
(2) 对比缓存 Last-Modified 和 If-Modified-Since Etag 和 If-None-Match
五、Ajax的优缺点
5.1 优点
- 页面无刷新,在页面内与服务器通信,减少用户等待时间,增强了用户体验。
- 使用异步方式与服务器通信,响应速度更快。
- 可以把一些原本服务器的工作转移到客户端,利用客户端闲置的能力来处理,减轻了服务器和带宽的负担,节约空间和宽带租用成本。
- 基于标准化并广泛支持的技术,不需要下载插件或依赖。
5.2 缺点
- 无法进行操作的后退,即不支持浏览器的页面后退。
- 对搜索引擎的支持比较弱。
- 可能会影响程序中的异常处理机制。
- 安全问题,对一些网站攻击,如csrf、xxs、sql注入等不能很好地防御。