前端请求的几种方式 标签、原生ajax、axios、fetch、websocket、beacon、sse

522 阅读3分钟

前端获取数据的方式 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 简化之前的写法 也可以只用awiat
  • fetch 返回的是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 {
      // 请求失败
  }
})

image.png

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()

image.png

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')
  }

image.png

beacon

信标(Beacon)可以异步与非阻塞的数据传输,从而最大限度地减少与其他关键操作的资源争用,同时它可以确保这些请求一定会被处理并将其传递到服务端: 一般使用的是上报前端的信息数据用

image.png