引言
最近捏麻麻的乱吃外卖给吃中毒了,这几天在回血的同时看了哈小满哥的网络杂记还是十分棒的。欲将轻骑逐;大雪满刀弓。
任务安排
-
fetch
-
SSE
-
sendBeacon
-
WebSocket
一:fetch
1.基本使用
fetch(url,{
method:'get/post',
headers:{//请求头格式
'Content-Type':'application/json'
}
})
2.get请求
前端
fetch('http://localhost:3000/test1').then(res=>{
return res.json()//将响应体数据解析成json
}).then(data=>{
console.log(data)
})
后端:koa2
router.get('/test1', async (ctx, next) => {
ctx.set("Content-Type",'application/json')
ctx.body = {
"name":"dzp"
}
})
3.post请求
前端
fetch('http://localhost:3000/test2',{
headers:{
'Content-Type':'application/json'
},
method:'post',
body:JSON.stringify({
name:'zhangsan',
age:18
})
}).then(res=>{
return res.json()
}).then(data=>{
console.log(data)
})
后端:koa2
router.post('/test2', async (ctx, next) => {
ctx.set("Content-Type",'application/json')
ctx.body = {
"name":"dzp"
}
})
4.取消请求
axios,fetch的取消请求已经趋于统一了,都是借助AbortController对象完成。
-
创建AbortController实例对象
-
请求体中添加signal属性
-
中断请求时调用abort()
<body> <div onclick="stopAsync()">click</div> <script> let control = new AbortController()//步骤1 fetch('http://localhost:3000/test3',{ headers:{ 'Content-Type':'application/json' }, method:'post', body:JSON.stringify({ name:'zhangsan', age:18 }), signal:control.signal//步骤2 }).then(res=>{ return res.json() }).then(data=>{ console.log(data) }) //取消按钮点击 function stopAsync() { control.abort()//步骤3 } </script> </body>
5.携带cookie
fetch在发起http请求时cookie无法自动携带,而axios是自动携带的。通过添加credentials:'include'可以自动携带cookie
fetch('http://localhost:3000/test3',{
credentials:'include',
}).then(res=>{
return res.json()
}).then(data=>{
console.log(data)
})
二:SSE
SSE(Server-Sent Events)指服务端向客户端主动发送消息的技术,它基于http长连接实现。sse仅支持单工通信,客户端无法向服务端发送消息。
1. Api介绍
url: 后端地址(必填)
option: 配置对象(选填)
const eventSource = new EventSource(url, {
withCredentials:false,//是否携带cookie,默认false
headers:{},//请求头类型
retryInterval:1000//与服务器失去连接时,重新连接的间隔时间
});
2. close()
eventSource.close()
3.onopen()
eventSource.onopen = function(e){
console.log('连接成功')
}
4.onerror()
eventSource.onerror = function(e){
console.log('连接失败')
}
5.onmessage()
eventSource.onmessage = function(e){
console.log('后端发送的消息',e)
}
6.操作例子
const sse = new EventSource("http://localhost:3000/json");
sse.onmessage = function(e) {
console.log('服务端发送的消息',e)
}
sse.onerror = funcction(e) {
console.log('连接失败')
}
三:sendBeacon
sendBeacon方法可用于通过 HTTP POST 将少量数据 异步 传输到 Web 服务器。它的操作十分简单
navigator.sendBeacon(url,data)
特点
优点
- 异步执行,不受页面卸载阻塞
- 支持跨域(太酷啦)
缺点
- 只支持post
- 仅发送少量数据64kb
- 无法自定义请求头格式,需要和后端约定好格式
使用场景
- 埋点
- 发送用户反馈
使用
//定义请求头格式
let headers = {
type: 'application/x-www-form-urlencoded'
};
//借助blob拼接数据和请求头
let blob = new Blob([JSON.stringify({name:"dzp"})], headers);
//发送数据
navigator.sendBeacon(this.data.requestUrl,blob)
四:websocket
sse适用于单工通信(服务端推送),那么websocket专门用于双工通信(客户端与服务端都可以发送接收消息)
1.基本API
创建对象
let websocket = new WebSocket('ws://localhost:3001');
监听连接成功
websocket.onopen = function(e) {
console.log('连接服务端成功')
}
监听连接断开
websocket.onclose = function(e) {
console.log('断开连接')
}
发送消息到服务端
websocket.send(msg)
接收服务端消息
websocket.onmessage = function(e) {
console.log('消息',e)
}
主动断开连接
websocket.close()
2. 1对1通信
前端
<body>
<button onclick="sendMsg()">发送消息</button>
<script>
let websocket = new WebSocket('ws://localhost:3001');
websocket.onmessage = function(e) {
console.log('服务端发送的消息',e.data)
}
websocket.onopen = function(e) {
console.log('连接服务端成功')
}
function sendMsg() {
if(websocket.readyState === 1) {
websocket.send(Math.random()*10)
}
}
</script>
</body>
后端 koa2
const ws = new WebSocket.Server({ port: 3001 });
ws.on('connection', socket => {//监听连接成功
socket.on('message', msg => {//获取客户端消息
let data = msg.toString()
socket.send(data)//向客户端发送消息
});
});
效果
两个客户端独立的向服务端发送消息,服务端将客户端发送的消息传递给前端。
3.群聊通信
上面的案例展示了如何单聊,那么如何实现广播?也就是群聊的方式?yeah,服务端在收到任意客户端消息时,拿到所有客户端,然后将当前信息广播出去就行了。
**前端**
<body>
<button onclick="sendMsg()">发送消息</button>
<script>
let websocket = new WebSocket('ws://localhost:3001');
websocket.onmessage = function(e) {
console.log('服务端发送的消息',e.data)
}
websocket.onopen = function(e) {
console.log('连接服务端成功')
}
function sendMsg() {
if(websocket.readyState === 1) {
websocket.send(Math.random()*10)
}
}
</script>
</body>
后端 koa2
const ws = new WebSocket.Server({ port: 3001 });
ws.on('connection', socket => {//监听连接成功
socket.on('message', msg => {//获取客户端消息
let data = msg.toString()
ws.clients.forEach(item=>{//群发消息
item.send(data)
})
});
});
效果
两个客户端独立的向服务端发送消息,服务端将客户端发送的消息传输到每个客户端。
4.心跳包
websocket在长时间未通信、弱网等情况下会自动关闭连接,为了保持其长连接效果,我们可以在前端或者后端开启定时器持续的向对方发送“心跳“数据保证长连接。
前端
<body>
<button onclick="sendMsg()">发送消息</button>
<script>
let websocket = new WebSocket('ws://localhost:3001');
websocket.onmessage = function(e) {
let data = JSON.parse(e.data)
if(data.state === 2) {//忽略心跳包数据
console.log('客户端受到消息',data.msg)
}
}
websocket.onopen = function(e) {
console.log('连接服务端成功')
}
websocket.onclose = function(e) {
console.log('断开连接')
}
function sendMsg() {
if(websocket.readyState === 1) {
websocket.send(Math.random()*10)
}
}
</script>
</body>
后端
const state = {
HEART:1,
MESSAGE:2
}
const ws = new WebSocket.Server({ port: 3001 });
ws.on('connection', socket => {
socket.on('message', msg => {//获取客户端消息
let data = msg.toString()
ws.clients.forEach(item=>{//群发消息
item.send(JSON.stringify({
state:state.MESSAGE,
msg:data
}))
})
});
let timer = null
const sendHeartMsg = () => {
if(socket.readyState === 1) {//连接成功状态
socket.send(JSON.stringify({
state:state.HEART,
msg:"心跳检测数据"
}))
}else {
clearInterval(timer)
}
}
timer = setInterval(sendHeartMsg,5000)
});