AjaxDay03
XMLHttpRequest
什么是 XMLHttpRequest?
是浏览器内置的一个构造函数
作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。
axios 中的 axios.get()、axios.post()、axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的!
使用 XMLHttpRequest 发起 GET 请求
get不携带参数
主要的 4 个实现步骤:
-
创建 xhr 对象
-
调用 xhr.open() 函数
-
调用 xhr.send() 函数
-
监听 load 事件
get携带带参数
可以在请求的 URL 地址后面
通过 ? 的形式携带查询参数
。示例代码如下:
使用 XMLHttpRequest 发起 POST 请求
携带查询参数
携带请求体参数
当需要携带请求体数据
时,需要进行额外的两步操作:
-
在 xhr.
open()
之后,调用 xhr.setRequestHeader()
函数,指定请求体的编码格式
-
在 xhr.
send()
中,指定要提交的请求体数据
XMLHttpRequest发送请求get请求传参与post请求传参的区别?
get请求
的参数需手动以键值对和&符号相连添加至url中,直接使用xhr.send()方法发送请求即可.
post请求
的参数如果是fd对象,则直接使用xhr.send(fd对象)发送请求
post请求
的参数如果是字符串类型,则需通过xhr.setRequestHeader(‘Content-Type’,‘application/x-www-form-urlencoded’)设置请求头中的编码格式,再通过xhr.send(字符串)发送请求
post请求
的参数如果是对象类型,则需将其转换为json格式字符串,通过xhr.send(JSON.stringify(对象))发送请求,其中同样需要通过xhr.setRequestHeader(‘Content-Type’,‘application/json’)设置请求头中的编码格式.
数据交换格式
数据交换格式,就是服务器端与客户端之间数据传输的格式,现在主要使用JSON交换格式
JSON(全称:JavaScript Object Notation)是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类型的数据。例如:
1.对象格式的 JSON 数据,最外层使用
{ }
进行包裹,内部的数据为key: value
的键值对结构。其中:①key 必须使用
英文的双引号
进行包裹②value 的值只能是字符串、数字、布尔值、null、数组、对象类型(可选类型只有这 6 种)
2.数组格式的 JSON 数据,最外层使用 [ ] 进行包裹,内部的
每一项数据之间
使用英文的 , 分隔。其中:
每一项的值类型只能是字符串、数字、布尔值、null、数组、对象
这 6 种类型之一。
把 JSON 数据转换为 JS 数据
调用浏览器内置的 SON.parse()
函数,可以把 JSON 格式的字符
串转换为 JS 数据
,例如:
把 JS 数据转换为 JSON 数据
调用浏览器内置的 JSON.stringify()
函数,可以把 JS 数据
转换为 JSON 格式的字符串
,例如:
JSON文件的语法要求
在 JSON 文件中定义 JSON 格式的数据时,要遵守以下的 6 条规则:
- 属性名必须使用双引号包裹
- 字符串类型的值必须使用双引号包裹
- JSON 中不允许使用单引号表示字符串
- JSON 中不能写注释
- JSON 的最外层必须是对象或数组格式
- 不能使用 undefined 或函数作为 JSON 的值
封装自己的 Ajax 函数
function SelfAjax(options) {
//初始化对象
const xhr = new XMLHttpRequest()
//处理get请求传参,本质上是将参数对象做处理后追加到url后面
if (options.params) {
let arr = []
for (k in options.params) {
arr.push(`${k}=${options.params[k]}`)
}
options.url +='?'+arr.join('&')
}
//准备数据
xhr.open(options.method, options.url)
//如果是post请求
if (options.method.toLowerCase() == 'post' && options.data) {
//如果data属性值是FormData类型,直接发送数据请求(fd为二进制对象,可不做编码处理)
if (options.data instanceof FormData) {
xhr.send(options.data)
}//如果data属性值是String类型,需定义头部请求中编码格式再发送数据请求(表单对象.serialize()可获取字符串类型的表单提交数据)
else if (typeof options.data === 'string') {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(options.data)
}//如果data属性值是Object类型,需定义头部请求中编码格式为json再发送数据请求
else if (typeof options.data === 'object') {
xhr.setRequestHeader('Content-Type', 'application/json')
//将object对象转换为json字符串
xhr.send(JSON.stringify(options.data))
}
} else {
//发送数据请求
xhr.send()
}
//监听onload事件,获得返回值
xhr.addEventListener('load', function () {
//将返回的json数据转换为js对象
let data = JSON.parse(xhr.response)
//服务器返回的数据交给函数调用的业务逻辑处理
options.success && options.success(data)
})
}
同源策略 & 跨域
什么是同源
?
同源指的是两个 URL 地址具有相同的协议、主机名、端口号。
例如,下表给出了相对于 http://www.test.com/index.html 页面的 5 个同源检测结果:
URL | 是否同源 | 原因说明 |
---|---|---|
http://www.test.com/other.html | 是 | 同源(协议、域名、端口相同) |
https://www.test.com/about.html | 否 | 协议不同(http 与 https) |
http://blog.test.com/movie.html | 否 | 域名不同(www.test.com 与 blog.test.com) |
http://www.test.com:7001/home.html | 否 | 端口不同(默认的 80 端口与 7001 端口) |
http://www.test.com:80/main.html | 是 | 同源(协议、域名、端口相同) |
什么是跨域
?
同源指的是两个 URL 的协议、主机名、端口号完全一致,反之,则是跨域。
出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互
。例如:
网页:http://www.test.com/index.html
接口:http://www.api.com/userlist
受到同源策略的限制,上面的网页请求下面的接口会失败!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ajNtr4At-1642253567805)(assets/1642211195677.png)]
突破浏览器跨域限制的三种方案
方案 | 诞生的时间 | 方案来源 | 优点 | 缺点 |
---|---|---|---|---|
JSONP | 出现较早 | 民间(非官方) | 兼容性好(兼容低版本 IE) | 仅支持 GET 请求 |
CORS | 出现较晚 | W3C 官方标准 | 支持 GET、POST、PUT、DELETE、PATCH等常见的请求方式 | 不兼容某些低版本浏览器 |
目前 JSONP 在实际开发中很少会用到
,CORS 是跨域的主流
技术解决方案。
第三种方式:反向代理,让本源的服务器向跨域的服务器请求数据并响应,本源服务器将响应的数据转发给浏览器.
请大家思考:实现 CORS 的关键,是在客户端还是在服务器端?
答案:服务器端。
原因:如果服务器端没有开启 CORS 功能,则客户端无法访问那些跨域的接口!一般由后端开启该功能.JSONP不是真正的Ajax技术
在解决跨域问题时:
CORS 方案用到了 XMLHttpRequest 对象,发起的是纯正的 Ajax 请求
JSONP 方案没有用到 XMLHttpRequest 对象,因此,JSONP 不是真正的 Ajax 技术结论:只要用到了 XMLHttpRequest 对象,发起的就是 Ajax 请求!
JSONP 的底层实现原理
JSONP 在底层,用到了
原因:
script 标签的 src 属性,不受浏览器同源策略的限制
可以把非同源的 JavaScript 代码
请求到本地,并执行
防抖 & 节流
防抖
什么是防抖?
防抖(debounce)指的是:频繁触发
某个操作时,只执行最后一次。
防抖的本质::利用setTimeou延时器
防抖应用场景
场景:搜索框只在输入完后,才执行查询的请求。
好处:这样可以有效减少请求的次数,节省网络资源。
核心代码:getSuggestList()方法是封装的根据用户输入文本获取服务器请求返回的搜索建议并展示到页面中的方法
节流
什么是节流?
节流(throttle)指的是:单位时间内,频繁触发
同一个操作,只会触发 1 次
。
节流应用场景
射击游戏中,单位时间内只能发射一颗子弹。
核心代码,isok为节流阀