Ajax
原生ajax
- 优点
- 页面无需刷新与服务器进行通讯获取数据
- 缺点
- 没有浏览历史,不能回退
- 存在跨域问题
- SEO不友好,不能进行SEO优化
基本实现
- 创建xhr实例
const xhr = new XMLHttpRequest()
- 配置发送请求方式、url
xhr.open('get','http://127.0.0.1:8080/xxx')
- 发送请求
xhr.send()
请求传参
ajax 有两种请求方式,get/post ,不同请求方式发送的参数格式也不同
GET
- query 参数
- 参数以 urlencoded 编码格式进行声明
?name=老刘&age=18xhr.open('get','http://127.0.0.1:8080/xxx?name=老刘&age=18')
- params 参数
- 参数以 路由 方式进行声明,服务端使用规则进行解析数据
/老刘/18xhr.open('get','http://127.0.0.1:8080/xxx/老刘/18')
POST
- query 参数
- 参数以 urlencoded 编码格式进行声明
?name=老刘&age=18xhr.open('post','http://127.0.0.1:8080/xxx?name=老刘&age=18')
- params 参数
- 参数以 路由 方式进行声明,服务端使用规则进行解析数据
/老刘/18xhr.open('post','http://127.0.0.1:8080/xxx/老刘/18')
- body 参数(请求体参数)
- 发送的参数需要传入在
xhr.send()中 - 有两种编码形式 urlencoded 和 json
- urlencoded 格式
xhr.send('name=老刘&age=18')
- json 格式
var person = {name:'老刘', age:18}xhr.send(JSON.stringify(person))
- urlencoded 格式
- 需要 配置 请求体参数编码形式的 请求头
- 需要在 open之后 send之前,或者 readyState 状态为 1 时,进行配置
- urlencoded 格式
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
- json 格式
xhr.setRequestHeader('Content-type', 'application/json')
- 发送的参数需要传入在
获取数据
获取一切数据,都需要在 onreadystatechange属性 定义的函数中进行获取
获取请求状态
- 为 xhr实例 的 onreadystatechange属性 赋值函数
- 当前状态发生改变时会触发此函数
- on:当xxx时候
- ready:准备
- state:状态
- change:改变
- 函数体中通过
xhr.readyState属性获取改变后的状态(1,2,3,4) - 应该在 new xhr之后 ,open之前 定义 ,如果在open之后定义,将获取不到状态1改变
获取http状态
- 为 xhr实例 的 onreadystatechange属性 赋值函数
- 函数体调用
xhr.status
获取数据
- 为 xhr实例 的 onreadystatechange属性 赋值函数
- 与 readyState 配合使用, 一般在状态为4时,调用
xhr.response
1 | |
设置获取数据类型
- 用于指定返回数据的格式
- 在 open 和 send 之间定义
- 直接返回 json 对象而不是字符串(将对返回的 json 字符串自动转为 json 对象)
1 | |
5种状态
- 状态:0
- 实例出来的那一刻状态就是0。初始状态
- 状态:1
- open已经调用了,但是send还没有调用
- 此时可以修改请求头内容
- 状态:2
- send已经调用了,已经无法改变请求头
- 状态:3
- 接收到所有响应头
- 并接收一部分数据,较大数据有待进一步接收
- 状态:4
- 数据全部接收完毕
- 即使 http 状态码为 404,ajax 依旧接收到了报错数据,所以请求状态会达到 4
异常处理
IE浏览器 get 缓存问题
问题原因
- IE 浏览器
- 相同 get 请求地址,IE浏览器会监测之前是否进行请求过,如果请求过直接使用之前缓存中的数据
- 谷歌浏览器
- 谷歌浏览器的开发者平台,可以通过设置走缓存,如果之前通过 get 请求过相同地址,再次请求时会与 服务器进行协商 ,如果服务端数据没有发生改变返回状态为 304,否则返回最新数据并且状态为 200,谷歌这种使用缓存的机制叫 协商缓存 304
解决 IE 不会与服务器进行协商,直接使用缓存
在 get 请求地址后面传一个时间戳参数,每次 get 地址不同就会重新向服务器发送请求
1 | |
请求报错
给 xhr 的 onerror 属性定义函数,当请求报错时调用此函数
1 | |
请求超时
- xhr 属性 timeout 定义等待时间,超时则取消请求
- xhr 属性 ontimeout 定义超时处理函数
1 | |
取消请求
- xhr 调用 abort() 方法,可以取消当前请求
- 如果请求已经返回,调用 abort() 没有任何效果
- 如果调用了 send() 之后,紧接着调用 abort(),就算请求数据返回也会被拒绝
1 | |
避免多次重复请求
- 点击发送请求时,事件处理函数中生成新的 xhr 对象,在全局作用域保存
- 全局作用域定义是否发送请求状态变量
- 每次点击时,检测是否发送了请求,如果发送则调用 abort() 函数
1 | |
jQuery中的ajax
完整
get
1 | |
post
1 | |
精简
get
1 | |
post
1 | |
跨域
跨域的原因
浏览器为了安全,采用的同源策略
同源策略
- 同源策略是由 Netscape 提出的一个安全策略,现在所有支持 Javascript 的浏览器都使用这个策略
- web 是构建在同源策略基础上的,浏览器只是针对同源策略的一种实现
所谓同源是指:前页面url和请求url,协议(http/https)、域名(IP)、端口 必须完全相同
同源策略限制
- Cookie 不能读取
- DOM 无法获取
- Ajax 请求不能获取数据(数据发送了也返回了,但是获取不到,浏览器不允许)
解决跨域
jsonp
只能通过 get 请求实现
发送 get 请求的情况
- from 表单
- xhr
- 浏览器地址栏
- img 标签
- script 标签
- link 标签
实现步骤
- 前端定义函数 demo
- 服务端返回的字符串,为 demo 调用的字符串
"demo({name:'小明', age:12})",参数为前端需要的数据 - 创建 script 标签节点
- 定义 script 标签 src 属性为请求的跨域地址
- 将 script 节点插入页面
- 当 script 节点插入页面,服务端返回的函数调用字符串自动执行,demo 函数中即可获取到数据
jquery 实现 jsonp
1 | |
cors
服务器给响应添加一组特殊响应头,允许浏览器接收数据
- Access-Control-Allow-Origin
- Access-Control-Expose-Headers
- Access-Control-Allow-Methods
HTTP 请求有4种
- get
- post
- put
- delete
服务端配置方式
- put、delete 请求在发送前,会进行以一次预请求(嗅探请求),必须在服务端添加一个 options 响应处理
- node.js 服务端,有个 cors 包,可以一次性配置所有响应处理
代理服务器
服务器给服务器发送请求,不受同源策略限制
- 数据发送给代理服务器
- 通过代理服务器给目标服务器发送请求
- 代理服务器接收到数据
- 再转发给客户端
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 蚂蚁图书馆!
