如何使用Socket.io与jQuery加载文件及传输二进制数组文件至服务器
嘿,我来帮你搞定这两个 Socket.io + jQuery 的文件操作问题,直接上实操性强的方案,都是可以直接复用的代码示例:
一、使用Socket.io和jQuery实现文件加载(从服务器获取文件)
核心思路是后端读取文件转为二进制数据,通过Socket.io发送给前端;前端接收后转成可下载的文件对象,配合jQuery完成交互。
后端(Node.js + Socket.io)
const fs = require('fs'); const path = require('path'); const http = require('http'); const socketIo = require('socket.io'); const server = http.createServer(); const io = socketIo(server); io.on('connection', (socket) => { // 监听前端的文件加载请求 socket.on('request-file', (fileName) => { const filePath = path.join(__dirname, fileName); // 读取文件为二进制Buffer fs.readFile(filePath, (err, data) => { if (err) { socket.emit('file-error', '文件读取失败'); return; } // 发送文件信息和原始二进制数据(Socket.io原生支持二进制传输) socket.emit('file-data', { name: fileName, type: 'application/octet-stream', // 可根据文件类型调整,比如image/png data: data }); }); }); }); server.listen(3000, () => console.log('服务器运行在3000端口'));
前端(jQuery + Socket.io)
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> $(document).ready(() => { const socket = io('http://localhost:3000'); // 点击按钮触发文件加载请求 $('#load-file-btn').click(() => { socket.emit('request-file', 'test.pdf'); // 替换成你要加载的目标文件名 }); // 接收服务器发来的文件数据 socket.on('file-data', (fileInfo) => { // 将二进制数据转为Blob对象 const blob = new Blob([fileInfo.data], { type: fileInfo.type }); // 创建下载链接并自动触发下载 const downloadLink = $('<a>').attr({ href: URL.createObjectURL(blob), download: fileInfo.name }); $('body').append(downloadLink); downloadLink[0].click(); downloadLink.remove(); }); // 处理加载错误 socket.on('file-error', (msg) => { alert('文件加载失败:' + msg); }); }); </script> <button id="load-file-btn">加载测试文件</button>
二、使用Socket.io和jQuery将二进制文件数组发送至服务器
核心是前端用FileReader把用户选择的文件转成Uint8Array(二进制数组),通过Socket.io发送给后端;后端将二进制数组转成Buffer后写入文件。
前端(jQuery + Socket.io)
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> $(document).ready(() => { const socket = io('http://localhost:3000'); // 监听文件选择框的变化 $('#file-input').change((e) => { const selectedFile = e.target.files[0]; if (!selectedFile) return; // 将文件转为Uint8Array二进制数组 const fileReader = new FileReader(); fileReader.onload = (event) => { const arrayBuffer = event.target.result; const uint8Array = new Uint8Array(arrayBuffer); // 发送文件元信息和二进制数组 socket.emit('upload-file', { name: selectedFile.name, type: selectedFile.type, data: uint8Array }); }; fileReader.readAsArrayBuffer(selectedFile); }); // 接收上传结果反馈 socket.on('upload-success', (msg) => { alert('文件上传成功:' + msg); $('#file-input').val(''); // 重置文件选择框 }); socket.on('upload-error', (msg) => { alert('文件上传失败:' + msg); }); }); </script> <input type="file" id="file-input" />
后端(Node.js + Socket.io)
const fs = require('fs'); const path = require('path'); const http = require('http'); const socketIo = require('socket.io'); const server = http.createServer(); const io = socketIo(server); const uploadDir = path.join(__dirname, 'uploads'); // 自动创建uploads目录(如果不存在) if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir); } io.on('connection', (socket) => { // 监听前端的文件上传事件 socket.on('upload-file', (fileInfo) => { const savePath = path.join(uploadDir, fileInfo.name); // 将Uint8Array转为Node.js的Buffer对象,写入文件 const fileBuffer = Buffer.from(fileInfo.data); fs.writeFile(savePath, fileBuffer, (err) => { if (err) { socket.emit('upload-error', '文件写入服务器失败'); return; } socket.emit('upload-success', `文件已保存至:${savePath}`); }); }); }); server.listen(3000, () => console.log('服务器运行在3000端口'));
小提示:如果是大文件,建议改成分块传输的方式,把文件拆成多个小块逐次发送,避免一次性传输过大数据导致性能问题。上面的示例是针对小文件的简化版,大文件场景可以扩展拆分逻辑~
内容的提问来源于stack exchange,提问作者MarkK
相关产品推荐
相关产品推荐

