Ajax
Ajax概述:
Ajax 异步的javaScript与xml 它可以完成对应的异步请求
ajax可以发送http请求
前端:发送请求 后端: 访问数据库 (请求)
数据库返回执行的内容—— 给到后端 ——后端进行处理 ——将数据响应到前端(响应操作)
内置对象 是请求对象
1.在请求的过程中 监听对应状态改变 (可以携带数据(cookie)和其他数据)
2.请求成功后从而获取到响应 (响应必须携带数据)
3.响应里面再读取到数据
Ajax特点:
1.支持异步请求
2.局部刷新(不会重新加载页面 而只改变页面的一部分)
3.局部刷新的时候可以保持浏览器不刷新(不会产生历史记录)
ajax的运用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9qiuM9uG-1656136619734)(C:\Users\MAC\AppData\Roaming\Typora\typora-user-images\image-20220414203633195.png)]
XMLHttpRequest(有兼容问题)
他是Ajax的核心对象(负责请求的对象)
1.封装方法
//兼容各大浏览器
function createXhr(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
}
return new ActiveXObject("Microsoft.XMLHTTP");
}
open方法 (打开一个地址以对应设置方式去请求)
xhr.open('GET',"https://jsonplaceholder.typicode.com/todos")
send方法(发送请求 它可以携带请求体)
xhr.send()
opreadystatechange 监听的事件
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && /^20\d$/.test(xhr.status)) {
}
}
readystate 一个请求状态码
0没有请求 1启动准备请求 2 请求已经发送 3 请求已发送且部分响应已经完成 4请求完成
status http状态码
1开头 表示已经成功需要继续操作
2开头 已经完成
3开头 重定向页面
4开头 客户端错误 404(找不到页面)
5开头 服务器错误 (500)
response Text 返回结果内容
xhr.responseText //他获取到的是string类型
responseXML 返回的xml类型的内容
xhl.responseXML
请求过程
1.创建一个请求对象
2.设置请求地址(携带数据)
3.发送请求
4.监听请求状态
5.请求完成以后 读取响应的数据
GET请求(打开浏览器) POST请求(表单提交)
get请求
Request 请求 response 响应
1.创建一个请求对象
let xhr = new XMLHttpRequest()
2.设置请求地址(携带数据)
xhr.open('GET',"https://jsonplaceholder.typicode.com/todos")
//参数1请求的方法 GET(打开浏览器) 请求 post请求(表单提交) 参数2为请求的地址
4.监听请求状态
xhr.onreadystatechange = function(){
5.请求完成以后 读取响应的数据
if(xhr.readyState == 4 && /^20\d$/.test(xhr.status)) {
console.log(xhr.responseText);//获取响应的内容 responseText
// response 返回响应体 responseText返回响应文本 responseType响应数据类型
}
}
3.发送请求
xhr.send()
GET请求的特点
1.他请求携带内容会在地址栏显示
2.浏览器默认的请求方式为GET
3.携带参数以?参数名=参数值&参数名=参数值
POST请求
1.创建请求对象
let xhr = createXhr()
2.set请求方式以及地址
xhr.open('POST','http://useker.cn/login')
6.设置请求头 key value 俩个都是string类型
xhr.setRequestHeader("content-type","application/javascript; charset=utf-8") //utf-8万国码 gb2312 gbk 国标码
3.发送请求 send里面 没有? 也是用&拼接
xhr.send('uname=1&upwd=2') //他里面的内容会放在请求体中
4.监听
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && /^20\d$/.test(xhr.status)){
5.接收响应
console.log(xhr.responseText);
}
}
post请求的特点
1.封装到请求体中
2.如果想使用post请求必须指定请求方式为post
3.post请求对应的安全性和携带性的内容比get强
4.post请求的效率低于get请求(表单提交使用post)
封装ajax
封装的特性 抽取共同的内容作为公共代码块(不同的内容做为参数)
不同点
请求方式 请求地址 回调函数 参数不一样 是否异步 参数类型不一样
ajax({
method: 请求方式
url: 请求地址
aync: 是否异步
ture 默认为以异步
data: 请求参数
dataType: 响应的参数类型
object 默认要做json.parse操作
callback: 回调
})
封装ajax
//兼容各大浏览器
function createXhr(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
}
return new ActiveXObject("Microsoft.XMLHTTP");//兼容ie6
}
function ajax(options){//options是一个对象
//先准备默认的对象 存储默认
let defaultObj = {
method:'GET', //默认为get请求
url:'', //必填
aync: true, //默认为异步请求
data: '',
dataType: 'json', //默认响应数据类型为json 默认需要JSON.parse
callback(){}
}
//url地址没有传递或者传递是空值 直接出去
if(!options.url || options.url==''){
throw new Error('url地址必须不为空') //抛出一个错误
}
//取出传递options里面的数据 给到defaultObj
for(let key in options){
defaultObj[key] = options[key] //将对应的key进行赋值
}
//后面使用的就是defaultObj
//判断method是否是get或者post 其他形式报错 全部大写
if(defaultObj.method.toUpperCase() != "GET" && defaultObj.method.toUpperCase() != "POST"){
throw new Error('请求方式错误') //抛出一个错误
}
//判断callback是否是函数类型
if(!typeof defaultObj.callback == "function"){
throw new Error('回调函数类型错误') //抛出一个错误
}
//判断aync是否为boolean类型
if(!typeof defaultObj.aync == "Boolean"){
throw new Error('aync必须是boolean类型') //抛出一个错误
}
//对于data的类型做一个判断 如果是string类型直接拼接 如果是对象类型 需要转为对应的string
if(defaultObj.data.toString() == "[object Object]"){ //如果你是string类型调用toString方法会直接返回对应内容
let dataStr = ""
for(let key in defaultObj.data){
dataStr+=key+'='+defaultObj.data[key]+"&"
}
//截图到最后一个&符号(把最后一个字符剔除)
dataStr = dataStr.slice(0,-1)
defaultObj.data = dataStr
}
//如果你是get请求 那么对应的请求数据和请求地址应该拼接
if(defaultObj.method.toUpperCase() == "GET"){
defaultObj.url+="?"+defaultObj.data
}
//创建一个请求对象
let xhr = createXhr()
//open请求地址
xhr.open(defaultObj.method.toUpperCase(),defaultObj.url)
//send发送请求
if(defaultObj.method.toUpperCase() == "POST"){
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(defaultObj.data)
}else{
xhr.send()
}
//监听请求
xhr.onreadystatechange = function(){
//接收响应
if(xhr.readyState == 4 && /^20\d$/.test(xhr.status)){
if(defaultObj.dataType == "json"){
let res = JSON.parse(xhr.responseText)//转换为json对象
defaultObj.callback(res) //调用回调方法 将对应响应结果带出
}else{
defaultObj.callback(xhr.responseText) //调用回调方法 将对应响应结果带出
}
}
}
}
回调地狱
无限的在回调函数里面进行回调函数的使用
<script>
//第一个请求
ajax({
url:'https://jsonplaceholder.typicode.com/todos/1',
callback(res){
//第二个请求
ajax({
url:'https://jsonplaceholder.typicode.com/todos/1',
callback(res){
//第三个请求
ajax({
url:'https://jsonplaceholder.typicode.com/todos/1',
callback(res){
console.log(res);
//..... 继续写对应的请求或者别的事件
}
})
}
})
}
})
</script>
这个代码的可维护性极低,代码的可阅读性也低(为了使异步的请求有同步执行的机制)
为了解决回调地狱的问题 这个时候js的es6 帮我们增加了一个promise的对象来帮我们解决这个问题