HTML 通过WebSocket接收文件并启动下载对话框

HTML无法直接通过WebSocket接收文件并启动下载对话框,需要结合后端语言如PHP、Node.js等实现。

HTML 通过WebSocket接收文件并启动下载对话框

单元1:简介

HTML 通过WebSocket接收文件并启动下载对话框

WebSocket是一种在浏览器和服务器之间进行双向通信的网络协议。

通过WebSocket,我们可以实现实时数据传输和低延迟的通信。

单元2:准备工作

HTML 通过WebSocket接收文件并启动下载对话框

在服务器端,需要创建一个WebSocket服务器来监听连接请求和发送文件数据。

在客户端,需要编写HTML代码来创建WebSocket连接,接收文件数据并启动下载对话框。

单元3:服务器端代码示例(Node.js)

HTML 通过WebSocket接收文件并启动下载对话框

const WebSocket = require('ws');
const fs = require('fs');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (socket) => {
  console.log('客户端已连接');
  const filePath = 'path/to/file'; // 文件路径
  const fileSize = fs.statSync(filePath).size; // 文件大小
  const fileName = 'file.txt'; // 文件名
  socket.sendUTF(${fileName};${fileSize}); // 发送文件名和大小给客户端
  const readStream = fs.createReadStream(filePath);
  readStream.pipe(socket); // 将文件内容通过WebSocket传输给客户端
});

单元4:客户端代码示例(HTML + JavaScript)

<!DOCTYPE html>
<html>
<head>
  <title>WebSocket文件下载</title>
</head>
<body>
  <button onclick="startDownload()">开始下载</button>
  <script>
    const socket = new WebSocket('ws://localhost:8080'); // WebSocket服务器地址和端口
    let receivedBytes = 0; // 已接收的字节数
    let totalBytes = 0; // 总字节数(文件大小)
    let filename = ''; // 文件名
    let downloadBlob = null; // 下载的文件对象(Blob)
    let downloadUrl = null; // 下载链接的URL
    let downloadAnchorElement = null; // 下载链接的锚元素(a标签)
    socket.binaryType = 'arraybuffer'; // 设置二进制数据传输类型为ArrayBuffer
    socket.onopen = () => {
      console.log('WebSocket连接已建立');
      socket.sendUTF('getFile'); // 向服务器发送获取文件的请求
    };
    socket.onmessage = (event) => {
      const dataView = new DataView(event.data); // 解析二进制数据流
      const messageType = dataView.getUint8(0); // 获取消息类型(1表示文件信息,2表示文件内容)
      const bytesReceived = dataView.getUint32(1, true); // 获取已接收的字节数(大端序)
      const bytesTotal = dataView.getUint32(5, true); // 获取总字节数(大端序)
      const filenameLength = dataView.getUint16(9, true); // 获取文件名长度(大端序)
      const filenameBytes = new Uint8Array(event.data, 13, filenameLength); // 获取文件名字节数组
      const filename = new TextDecoder().decode(filenameBytes); // 解码文件名字符串
      console.log(已接收 ${bytesReceived} / ${bytesTotal} 字节,文件名为 ${filename});
      receivedBytes += bytesReceived; // 更新已接收的字节数
      totalBytes = bytesTotal; // 更新总字节数(文件大小)
      if (messageType === 1) { // 如果消息类型为1,表示是文件信息,保存相关信息以供后续使用
        filename = filename; // 保存文件名到全局变量中
        downloadUrl = URL.createObjectURL(new Blob([event.data])); // 创建下载链接的URL(暂时用整个事件数据作为Blob)
        downloadAnchorElement = document.createElement('a'); // 创建下载链接的锚元素(a标签)
        downloadAnchorElement.href = downloadUrl; // 设置下载链接的URL属性为之前创建的URL
        downloadAnchorElement.download = filename; // 设置下载链接的文件名为之前保存的文件名
        document.body.appendChild(downloadAnchorElement); // 将下载链接添加到页面中,但不立即触发点击事件(避免提前下载)
      } else if (messageType === 2) { // 如果消息类型为2,表示是文件内容,将内容添加到Blob对象中以供后续下载使用
        if (!downloadBlob) { // 如果还没有创建Blob对象,则先创建一个空的Blob对象作为初始值
          downloadBlob = new Blob();
        } else { // 如果已经创建了Blob对象,则将新收到的内容添加到已有的Blob对象中(追加方式)
          const contentBlob = new Blob([event.data]); // 根据事件数据创建一个新的Blob对象(内容部分)
          const finalBlob = new Blob([downloadBlob, contentBlob], { type: 'application/octetstream' }); // 根据已有的Blob对象和新的Blob对象创建一个新的Blob对象(合并方式)
          downloadBlob = finalBlob; // 更新下载的文件对象为最终的Blob对象(包含所有内容的Blob)
        }
      } else { // 如果消息类型既不是1也不是2,则忽略该消息不进行处理(保留其他可能的消息类型处理逻辑)
        console.warn(未知的消息类型:${messageType});
      }
    };
    socket.onclose = () => {
      console.log('WebSocket连接已关闭');
      if (downloadAnchorElement) { // 如果存在下载链接的锚元素,则将其从页面中移除并触发点击事件以启动下载对话框(可选操作)

原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/490284.html

(0)
未希新媒体运营
上一篇 2024-04-19 01:10
下一篇 2024-04-19 01:11

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

云产品限时秒杀。精选云产品高防服务器,20M大带宽限量抢购  >>点击进入