前端获取数据的方式 dom标签、原生ajax、axios、fetch、websocket、beacon、sse
1.DOM 标签请求
<a>、<img>、<link>、<script>、<iframe>、<video> 、<audio> 等标签如下:
<a href="https://ask.dcloud.net.cn/protocol.html">test demo</a>
<img src="./images/z-1.png"/>
<link rel="stylesheet" href="demo.css">
<script src="demo.js" />
<iframe href="https://demo.com"></iframe>
<video src="demo.mp4"></video>
<audio src="demo.mp4"></audio>
2.ajax 原生异步请求
let xhr = new XMLHttpRequest()
xhr.open('GET', 'http://192.168.10.21:9202/yw/', true)
xhr.onreadystatechange = function (res) {
if (xhr.readyState === 4 || xhr.status === 200) {
// 响应成功处理请求
console.log(res)
} else {
// 响应失败
console.log(res)
}
}
xhr.send()
//补充说一下 onreadystatechange 和 onload 之间的区别
//onreadystatechange 是一个通用的事件处理器 每次的readyState改变都会被触发
//readyState 值为0:初始化1正在加载2加载完成3交互中4完成 处理4时候或者status为200的时候
// onload 比较更常用,是请求完全加载完成不需要检查readyState 更简洁 如下:
xhr.onload = function () {
if (xhr.status === 200) {
// 响应成功处理请求
console.log(res)
} else {
// 响应失败
console.log(res)
}
}
xhr.send()
3.axios api 请求
这个是根据原生ajax封装成,使用更简单,可以直接在项目中安装使用
# npm install axios
import axios from 'axios'
axios({
url: 'http://192.168.10.21:9202/yw/',
method: 'POST',
data: data,
headers: {
'Content-Type': ''
}
}).then((res) => {
console.log(res)
})
4.fetch 请求
fetch()也是 XMLHttpRequest 封装而成,浏览提供了fetch API ,这里和 XMLHttpRequest区别有以下几点
fetch使用Promise 简化之前的写法 也可以只用awiatfetch返回的是Stream 需要手动转化一下JSON response.json()fetch使用的是模块化设计,API分散在 Header、Resquest上,使用起来更明确 参数变化
const res = await window.fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // 这里注意一下是需要转化成string 这里的入参也参数名称是 body 不是 data
if(res.ok) {
// 请求成功
} else {
// 请求失败
}
})
5.webscoket 请求
webcoket 是双向通信 解决了HTTP 的缺陷(通信只能由客户端发起),HTTP协议做不到服务器发起像客户端推送信息,如果实现类似的需求,那就是需要前端轮询向服务端发起请求(聊天、股票等需要及时通信的任务)。轮询的效率低,而且不一定及时。解决这个问题最好的办法就是webscoket。
如描述实现了双向通信,主要特点如下:
- 实时性比较高,减少网络请求
- 支持双向通信
- 支持跨域
- 安全性比较高
- 协议表示标识是ws,代码封装如下:
const DEFAULT_CHECK_TIME = 5* 1000 //心跳监测默认时间
const DEFAULT_CHECK_COUNT = 3; // 心跳检测默认失败重连次数
class wsWebSocket {
heartCheckTimeout = DEFAULT_CHECK_TIME
heartCheckCount = DEFAULT_CHECK_COUNT
heartCheckInterval = null
constructor(url) {
this.socket = new WebSocket(url);
this.eventListener = {}
this.socket.onopen = (event) => {
this.trigger('open');
};
this.socket.onclose = (event) => {
this.trigger('close');
};
this.socket.onmessage = (event) => {
this.trigger('message', event.data);
};
this.socket.onerror = (error) => {
this.trigger('error', error);
};
}
trigger(event, ...data) {
if (this.eventListener[event]) {
// Call the event method, passing in the provided data.
this.eventListener[event].forEach(callback => callback(data));
}
}
send(message) {
this.socket.send(message)
}
close() {
this.close()
}
// 开始心跳检测
heartCheckStart(data) {
this.heartCheckInterval = setTimeout(() => {
this.send(data)
this.heartCheckStart()
}, this.heartCheckTimeout)
}
}
const url = 'https://demo'
const ws = new wsWebSocket(url)
ws.send('hello websocket')
ws.close()
sse请求
服务器向浏览器推送信息,除了 WebSocket,还有一种方法:Server-Sent Events 与 websoket 的区别是这个是一个单项通信,只能服务器向浏览器发送,因为流信息本质上就是下载 具体与websocket 的区别有如下:
- 协议还是HTTP 协议,websocket是一个独立的协议
- SSE 更轻量级,简单
- SSE一般用于数据流传输,文本二进制,使用场景,如视频下载,加载整个流太大,时间太长,可以边加载边播放
- SSE 支持自定义发送消息类型
const sse = new EventSource('https://aigc4cs.wanlianyida.com/cs_answer?input=你好', {
withCredentials: true
})
sse.onmessage = e => {
console.log(e.data, 'onmessage')
}
sse.onopen = e => {
console.log(e, 'open')
}
sse.onerror = e => {
console.log(e, 'error')
}
beacon
信标(Beacon)可以异步与非阻塞的数据传输,从而最大限度地减少与其他关键操作的资源争用,同时它可以确保这些请求一定会被处理并将其传递到服务端: 一般使用的是上报前端的信息数据用