AJAX
概念
- AJAX = Asynchronous JavaScript and XML(异步的JavaScript 和 XML)
- 使用内置的XMLHttpRequest 和 fetch 对象,实现和服务端进行数据交互
- 优点: 交互数据时页面不需要刷新,体验较好
- 反正是浏览器内部的一个对象,用的时候调用
如何与后端交互
一般来说有三种
form表单
- 只支持GET和POST
- 有问无答,体验不佳
AJAX
- 使用下面两个API
- XMLHttpRequest
- Fetch
Websocket
- 可以由服务器端主动发起
XMLHttpRequest(GET请求)
那么现在就来看看XMLHttpRequest,举例发送一个GET请求
- 先使用XMLHttpRequest创建一个对象
- 然后配置参数
- 绑定事件
- 最后发送请求
let xhr = new XMLHttpRequest()//创建一个对象
xhr.open('GET',url,true)//GET方法,接口,异步
xhr.onload = function(){}
xhr.send()
举例
常规的写法
let url = 'http://rap2api.taobao.org/app/mock/244238/weather?city=北京'
let xhr = new XMLHttpRequest()
xhr.open('GET',url,true)
xhr.onload = function(){
if((xhr.status>=200&&xhr.status<300)||xhr.status===304){
console.log(xhr.response)
}else{
onsole.log('数据异常')
}
}
xhr.responseType='json'//兼容性比较差
xhr.onerror=function(){
console.log('服务器异常')
}
xhr.send()
## XMLHttpRequest(POST请求)
涉及到用户登录,注册,用户信息填写这方面,而不是查询,就要用到POST请求
- 创建对象
- 配置XMLHttpRequest,使用POST
- 可选请求超时时间
- 设置请求头部的内容类型
let url = 'http://rap2api.taobao.org/app/mock/244238/login'
let xhr = new XMLHttpRequest()
xhr.open('POST',url,true)
xhr.time = 3000
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
xhr.onload = function(){
if((xhr.status>=200&&xhr.status<300)||xhr.status===304){
console.log(JSON.parse(xhr.responseText))
}else{
onsole.log('数据异常')
}
}
xhr.ontimeout=function(){console.log('请求超时')}
xhr.onerror=function(){console.log('服务器异常')}
xhr.send('username=hunger&password=12345678')
同步 VS 异步
- 异步需要绑定onload方法,需要在onload的函数里操作我们的方法
- 使用同步,不需要去监听事件.
- 发出去以后直接拿到结果.
- 缺点是太慢,因为使用同步,一个任务完成再进行下一个任务
let url = 'http://rap2api.taobao.org/app/mock/244238/weather?city=北京'
let xhr = new XMLHttpRequest()
xhr.open('GET',url,false)
xhr.send()//可能卡在这里很久,因为js是单线程的.所以别用同步
let result = JSON.parse(xhr.responseText))
console.log(result)
使用AJAX封装
上面代码可以看到,每次都写url什么的实在是太麻烦了,难道每次又要去自己重新写吗.
作为一条懒狗,我们可以把他封装起来,下次用的时候调用就行了.
GET请求的封装
- 设置一个函数
- 函数形参分别设置为:url,参数,成功的函数,错误时的函数
- 然后用这个api,可以把对象转换成数列,经过一系列处理下面这个样子,具体步骤如下
- Object.entries({params)
const request =(url,params,onsuccess,onerror) =>{
url = url+ '?' + Object.entries(params).map(arr => arr[0]+'='+arr[1]).join('&')
let xhr = new XMLHttpRequest()
xhr.open('GET',url,true)
xhr.onload=function(){
if((xhr.status>=200&&xhr.status<300)||xhr.status===304){
onsuccess(JSON.parse(xhr.responseText))
}else{
onerror()
}
}
xhr.onerror = onerror
xhr.send()
}
request('http://rap2api.taobao.org/app/mock/244238/weathe',{city:'杭州'},
data=>{
console.log('请求成功')
console.log(data)},
()=>{console.log('接口异常')})
POST请求编码的方式,即'Content-type'
后面的设置字段
- 告诉服务器请求参数的b编码方式
- application/x-www-form-urlencoded
参数变成key1=value1&key2=value2的形式 - multipart/form-data
一般上传文件用
POST登录验证
letformData=newFormData()
formData.append('username','abcdefg')
formData.append('password','123456')
let url='http://rap2api.taobao.org/app/mock/244238/register'
let xhr=newXMLHttpRequest()
xhr.open('POST',url,true)xhr.onload=function(){
if(xhr.status===200||xhr.status===304){console.log(JSON.parse(xhr.responseText))
}else{
console.log('接口异常')
}}
xhr.send(formData)
POST发送的实际案例
const $ = s =>document.querySelector(s)
const $submit = $('[type=submit]')
const $form = $('form')
const $msg = $('#msg')//先把所有的表单元素选中
let url = 'xxx'
//然后监听提交按钮的提交事件
$form.onsubmit = function(e){
e.preventDefault()//阻止form提交的默认事件
let formData = new FormData('$form')//可以把选中的form表单塞进去,然后form里的内容就会自动存在这个对象里
let xhr = newXMLHttpRequest()
xhr.open('POST',url,true)
xhr.onload=function(){
if(xhr.status===200||xhr.status===304){
letdata=JSON.parse(xhr.responseText)
$msg.innerText = data.msg
}else{
$msg.innerText='接口异常'
}}
xhr.send(formData)//最后把对象里的内容发送出去
}
fetch
比上面的那个简单很多
对于GET请求
let url = 'xxx'//设置接口
//然后直接调用fetch就好
fetch(url).then(response=>response.json()).then(data=>{document.body.innerText=data.results[0].weather_data[0].weather})
对于PSOT请求
对于PSOT请求呢,使用fetch要配置一些参数
let url = 'xxx'
let data = {a:1,b:2}
fetch(url,{method:'POST',body:Object.entries(data).map(arr=>arr[0]+'='+arr[1]).join('&'),headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(res=>res.json()).catch(error=>console.error('Error:',error)).then(response=>console.log('Success:',response))
关于ajax的双工通信
何谓双工通信?双工通信就是有来有往
Ajax轮询
每隔固定时间发一次请求
- 发请求,服务器响应,返回空
- 发请求,服务器响应,返回数据
- 发请求,服务器响应,返回空
- 发请求,服务器响应,返回空
- 优点:简单
- 缺点:
长轮询
客户端
- 客户端发请求给服务器,等待响应,服务器不会第一时间给数据
- 服务器有了数据,然后返回给客户端,客户端得到了数据
- 客户端得到了数据,再发一次请求,就这么循环.(可以写个递归)
服务器 - 请求到来,如果没有新数据,就不返回
- 有新数据了,先通知客户端,再响应