网络 AJAX、Fetch、WebSocket的基本认识(分享)

1. AJAX

1.1 基本概念
  • AJAX是一门异步的用于发送网络请求的计算
  • 允许浏览器与服务器通信,而无序刷新当前页面的技术叫做 AJAX
  • AJAX是 Asynchronous JavaScript and XML 的缩写
1.2 GET请求步骤
// 1.创建请求对象
const XHR = new XMLHttpRequest()

// 2.设置请求对象
XHR.open("GET", "http://xxx:9527/xxx")

// 3.设置请求头,GET请求不需要设置请求头
// XHR.setRequestHeader()

// 4.发送请求
XHR.send()

// 5.监听请求的状态
XHR.onreadystatechange = function () {
  // XHR.readyState ==> 请求过程
  // (1).请求未初始化,在open之前       --> 0
  // (2).服务器连接已经建立,在open之后  --> 1
  // (3).请求已经接收                  --> 2
  // (4).请求处理中                    --> 3
  // (5).请求已完成,且响应已经就绪       --> 4

  // 6.处理请求结果
  if (XHR.readyState === 4) {
    // XHR.status 请求状态码
    if (XHR.status >= 200 && XHR.status < 300) {
      // 返回的是JSON格式
      console.log(JSON.parse(XHR.response));
    } else {
      console.log("请求失败");
    }
  }
}

// 7.超时处理
// 终止请求
XHR.timeout = 10000

// 取消请求
XHR.abort();
1.3 POST请求步骤
// 1.创建请求对象
const XHR = new XMLHttpRequest()

// 2.设置请求对象
XHR.open("POST", "http://xxx:9527/xxx")

// 3.设置请求头
// POST:提交数据需要告知服务端数据格式(设置请求头)
// application/x-www-form-urlencoded --> name=xiaohong&age=18
// application/json --> JSON.stringify({"name": "xiaohong","age": 18})
XHR.setRequestHeader("Content-Type", "application/json")

let params = { "name": "鲁班", "words": "鲁班大师智商250" }
// 4.发送请求
XHR.send(JSON.stringify(params))

// 5.监听请求的状态
XHR.onreadystatechange = function () {
  // XHR.readyState ==> 请求过程
  // (1).请求未初始化,在open之前       --> 0
  // (2).服务器连接已经建立,在open之后  --> 1
  // (3).请求已经接收                  --> 2
  // (4).请求处理中                    --> 3
  // (5).请求已完成,且响应已经就绪       --> 4

  // 6.处理请求结果
  if (XHR.readyState === 4) {
    // XHR.status 请求状态码
    if (XHR.status >= 200 && XHR.status < 300) {
      // 返回的是JSON格式
      console.log(XHR.response);
    } else {
      console.log("请求失败");
    }
  }
}

// 7.超时处理
// 终止请求
XHR.timeout = 10000
1.4 AJAX封装
function _$(data, callback) {
  // 用变量存一下属性,请求GET和POST默认转为大写
  let method = data.method.toLocaleUpperCase()
  let url = data.url
  let params = data.params

  // 如果请求方式为空,默认为 GET 请求
  if (!method) {
    method = "GET"
  }

  const XHR = new XMLHttpRequest()

  // 如果为 GET 请求需要拼接路径,并且需要有参数
  if (params) {
    XHR.open(method, url + (method === "GET" ? `?${params}` : ""))
  } else {
    XHR.open(method, url)
  }

  // 如果为 POST 请求,设置请求头
  if (method === "POST") {
    // POST 请求,限制数据为json格式
    XHR.setRequestHeader("Content-Type", "application/json")
    // 如果有数据,发送数据
    XHR.send(params ? JSON.stringify(params) : null)
  } else {
    XHR.send()
  }

  XHR.onreadystatechange = function () {
    if (XHR.readyState === 4) {
      if (XHR.status >= 200 && XHR.status < 300) {
        callback && callback(XHR.response)
      } else {
        callback && callback("错误")
      }
    }
  }

  // 超时,终止请求
  XHR.timeout === 10000
}

2. fetch

2.1 基本概念
  • fetch 被称为下一代 AJAX 技术,采用 Promise 方式处理数据,是一种简单明了的 API
  • 使用 fetch 会发送 http 请求给服务器,在不刷新网页的情况下,可以实现局部内容的更新
  • 当接收到一个错误的HTTP状态码时,从 fetch() 返回的 Promise 不会返回 reject 会返回 resolve,当网络故障或请求被阻止时,才会调用 reject
2.2 GET请求案例
<!-- html部分 -->
<button>点击获取图片</button>
<img src="" alt="">
// js部分,fetch只用传入参数就可以请求数据
let btn = document.querySelector("button")
let img = document.querySelector("img")
btn.addEventListener("click", function () {
  let controller = new AbortController()
  // fetch 会返回一个 Promise 对象,请求默认为 GET
  fetch("https://dog.ceo/api/breeds/image/random", {
  	signal: controller.signal
    }) // 随机出一张图片的网址
    .then(res => {
      // 这里的res还是一个promise对象
      // 需要调用json(),再次返回包含数据的promise
      return res.json()
    }).then(data => {
      // data.status 要看后端接口的数据格式
      if (data.status === "success") {
        img.src = data.message
      } else {
        throw new Error("出错了")
      }
    }).catch(err => {
      throw new Error(err)
    })

  // 取消请求
  AbortController.abort()
})
2.3 POST请求案例
<!-- html部分 -->
<input type="text" value="我是要被传输的数据~~">
let input = document.querySelector("input")
input.addEventListener("click", function () {
  // fetch 会返回一个 Promise 对象,默认为 GET 请求
  fetch("https://xxx/xxx/xxx", { 
    // 它的第二个参数为一个对象,可以设置对应的配置
    method: "POST",
    body: JSON.stringify({ name: input.value }),
    headers: {
      "Content-Type": "application/json"
    }
  })
    // 这里和GET的处理差不多
    .then(res => res.json()).then(data => data).catch(err => err)
})

3. WebSocket(H5)

3.1 基本概念
  • WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

  • WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

3.2 WebSocket的属性和方法
3.2.1 属性
属性描述
Socket.readyState只读属性 readyState 表示连接状态,可以是以下值:
       0 - 表示连接尚未建立。
       1 - 表示连接已建立,可以进行通信。
       2 - 表示连接正在进行关闭。
       3 - 表示连接已经关闭或者连接不能打开。
Socket.bufferedAmount只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
3.2.2 事件
事件事件处理程序描述
openSocket.onopen连接建立时触发
messageSocket.onmessage客户端接收服务端数据时触发
errorSocket.onerror通信发生错误时触发
closeSocket.onclose连接关闭时触发
3.2.3 方法
方法描述
Socket.send()使用连接发送数据
Socket.close()关闭连接
3.3 WebSocket实现聊天室
  • 首页采用了两个页面,聊天室入口、聊天室,用 gulp 开启的服务,vscode 插件也可以
  • 后端采用的 ws 这个库

聊天室入口部分 index.html

<!-- html文件 -->
<input type="text" placeholder="请输入用户名" id="username">
<button id="btn">进入聊天室</button>
// js文件
// 主要就是记录是哪个用户进入的聊天室
((doc, storage, location) => {
  let username = doc.querySelector("#username")
  let btn = doc.querySelector("#btn")
  let init = () => {
    bindEvent()
  }
  function bindEvent() {
    btn.addEventListener("click", headEventBtnClick, false)
  }
  function headEventBtnClick() {
    let usernameInfo = username.value.trim()
    if (usernameInfo.length < 2) {
      alert("长度不能小于2个字符")
      return
    }
    // 输入用户名,本地存储用户名,进入聊天页
    storage.setItem("username", usernameInfo)
    location.href = "/chatPage.html"
  }
  init()
})(document, localStorage, location)

聊天室部分 chatPage.html

<!-- html文件 -->
<style>
  .username {
    color: red;
  }

  .msg {
    background-color: #008c8c;
    color: white;
    font-weight: bold;
    padding: 4px;
  }
</style>

<h2></h2>
<ul id="list"></ul>
<input type="text" id="message" placeholder="请输入消息">
<button id="send">发送消息</button>
// js文件
class Demo {
  constructor() {
    // 确认是哪个用户的聊天室
    document.querySelector("h2").innerHTML = `聊天室:${localStorage.getItem("username")}`
    this.list = document.querySelector("#list")
    this.msg = document.querySelector("#message")
    this.sendBtn = document.querySelector("#send")
    // 本地连接,端口:9527
    this.ws = new WebSocket("ws:localhost:9527")
    // 存用户的名字,也就是谁发送的这条消息
    this.username = ""

    this.init()
  }
  init() {
    this.bindEvent()
  }
  bindEvent() {
    // 会有 this 指向问题,用 bind 绑一下
    this.sendBtn.addEventListener("click", this.sendClick.bind(this))
    this.ws.addEventListener("open", this.handleOpen.bind(this))
    this.ws.addEventListener("close", this.handleClose.bind(this))
    this.ws.addEventListener("error", this.handleError.bind(this))
    this.ws.addEventListener("message", this.handleMessage.bind(this))
  }

  sendClick() {
    let msg = this.msg.value.trim()
    // 如果为空什么都不做
    if (msg.length === 0) {
      return
    }

    // 发送数据
    this.ws.send(JSON.stringify({
      username: this.username,
      dateTime: +new Date(),
      msg
    }))

    this.msg.value = ""
  }

  handleOpen() {
    // 是哪个用户发送的消息,需要知道
    this.username = localStorage.getItem("username")
  }

  handleClose() {
    console.log("ws close");
  }

  handleError() {
    console.log("ws error");
  }

  // 接收后端返回的数据
  handleMessage(e) {
    const { username, dateTime, msg } = JSON.parse(e.data)
    // 把数据结合标签添加到页面上
    let li = document.createElement("li")
    li.innerHTML = `
      <p>用户:<span class="username">${username}</span></p>
      <p>时间:${new Date(dateTime)}</p>
      <p>消息:<span class="msg">${msg}</span></p>
    `
    this.list.appendChild(li)
  }
}

new Demo()

后端部分

// 后端就随便写一下
const ws = require("ws")

// 后端与前端端口一致
const server = new ws.Server({ port: 9527 })

// 连接时触发
server.on("connection", function (ws) {
  console.log("server connection");
  // 接收客户端发来的数据,并广播出去(每一位连接的用户都可以接收到)
  ws.on("message", function (msg) {
  	// 多个ws的集合
    server.clients.forEach(item => {
      // 传过来的是 Buffer,要转一下
      item.send(msg.toString())
    })
  })
  
  // 关闭时触发
  ws.on("close", function (code, reason) {
    console.log("close", code, reason);
  });
})

聊天室效果图如下:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket聊天室是使用Web技术实现实时双向通信的一种常见方式,结合Spring Boot、Vue.js和MySQL,可以构建一个高性能的后台服务器与前端交互的应用。下面是一个简要的概述: 1. **Spring Boot**: 作为Java的轻量级框架,Spring Boot简化了配置过程,提供了快速启动web应用的能力。你可以利用Spring Websocket来处理WebSocket连接和消息传递。 2. **Vue.js**: 这是一个流行的JavaScript前端框架,用于构建用户界面。在Vue中,你可以创建WebSocket的连接,实现实时数据更新和事件驱动的通信。 3. **MySQL**: 作为关系型数据库,MySQL存储聊天室中的用户信息、会话记录以及消息内容。通过AjaxFetch API,你可以将前端发送的数据保存到MySQL,并在需要时查询更新的数据展示给用户。 **实现步骤:** - **后端(Spring Boot)**: - 创建WebSocket配置,比如`org.springframework.messaging.handler.annotation.MessageMapping`注解处理WebSocket消息。 - 建立数据库模型,如User、Session表,以及Message实体。 - 使用JPA进行数据库操作,实现增删改查。 - **前端(Vue.js)**: - 使用WebSocket库(如`WebSocket`原生API或第三方库`vue-websocket`)建立连接。 - 用户界面设计,包括输入框、聊天列表和发送按钮。 - 实现消息的发送和接收功能,利用Vue的响应式特性实时更新显示。 **相关问题--:** 1. Spring Boot如何启用WebSocket支持? 2. Vue.js如何初始化WebSocket连接并处理接收到的消息? 3. 如何确保Vue前端与Spring Boot后端的数据同步?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值