HTML 通過(guò)WebSocket接收文件并啟動(dòng)下載對話(huà)框
時(shí)間:2026-05-04 23:15:14HTML 通過(guò)(guo)WebSocket接收文件并啟動(dòng)(′?`)下載對話(huà)框(//ω//)
單元1:簡(jiǎn)介
WebSocket是啟動(dòng)一種在瀏覽器和服務(wù)器之間進(jìn)行(????)雙向通信的網(wǎng)絡(luò )協(xié)??議。
單元2:準備工作
在服務(wù)器ヾ(′?`)?端,通過(guò)需要創(chuàng )建一個(gè)WebSocket服務(wù)器來(lái)監聽(tīng)連接請求和發(fā)送文件數據。接件并
在客戶(hù)端,收文需要編寫(xiě)HTML代碼來(lái)??創(chuàng )建WebSocket連接,啟動(dòng)接收文件數據并啟動(dòng)下載對話(huà)框。下載
單元3:服務(wù)器端代碼示例(Node.js)
const WebSocket = require('ws');const fs = require('fs');const server = new WebSocket.Server({ port: 8080 });serv??er.on('connection',對??話(huà) (socket) => { console.log('客戶(hù)端已連接'); const filePath = 'path/to/file'; // 文件路徑 co(′▽?zhuān)?nst fileSize = fs.statSync(filePath).size; // 文件大小 const fileName = 'file.txt'; // 文件名 sock??et.sendUTF(${ fileName};${ fileSize}); // 發(fā)送文件名和大小給客戶(hù)端 const readStre??am = fs.createReadStream(fi( ?ω?)lePath); readS??tream.pipe(socket); // 將文件內容通過(guò)WebSocket傳輸給客戶(hù)端});單元4:客戶(hù)端代碼示例(HTML + Ja(?Д?)vaScript)
&l??t;!DOCTYPE html&??gt;<ht(°o°)ml><head> <title>ヽ(′ー`)ノ;WebSocket文件下載</title></head><(′?ω?`)body> <button onclick=&ヾ(′ω`)?quot;startDownl??oad()">開(kāi)始下載</button&g??t; <script> const socket = new WebSocket('ws://localho??st:8080')ˉ\_(ツ)_/ˉ; // WebSocket服務(wù)器地址和端口 let receivedBytes = 0; // 已接收的字節數 let totalBy??tes = 0; // 總字節數(文件( ?° ?? ?°)大?。?let filename(′▽?zhuān)? = ''; // 文件名 let downloadBlob = null; // 下載的文件對象(Blob)(⊙_⊙) let downloadUrl = null; // 下載鏈接的URL let downloadAnchorElement = null; // 下載鏈接的錨元素(a標簽) socket.binaryType = 'arraybuffer'; // 設置二進(jìn)制數據(ju)傳輸類(lèi)型為Arr(′ω`)ayBuffer soc(??ヮ?)?*:???ket.onopen = () => { console.log('WebSocket連接已建立'); socket.sendUTF('getFile'); // 向服務(wù)器發(fā)送獲取文件的請求 }; socket(′;ω;`).onmessage = (event) => { const dataVi??ew = new DataView(event.data); // 解析二進(jìn)制數據流 const messageType = dataView.getUint8(0); // 獲取消息類(lèi)型(??1表示文件信息,2表示文件內容) const byteヽ(′?`)ノsReceived = dataView.getUint32(1,通過(guò) true); // 獲取已接收的字節數(大端序) const bytesTotal = dataView.getUint32(5, true); // 獲取??總字節數(大端序) const filenameLengthヾ(^-^)ノ = dataView.getUint16(9, true); // 獲取文件名長(cháng)度(大端序) const filenameBytes = new Uint8Array(event.data, 13, filenameLength); // 獲取文件名字節數組 const filename = new TextDecoder().decode(filenameBytes); // 解碼文件名字符串 console.log(已接收 ${ bytesReceived} / ${ bytesTotal} 字節,文??件名為 ${ filename}); receivedBytes += bytesReceived; // 更新已接收的接件并字節數 totalBytes = bytesTotal; // 更新總字節ˉ\_(ツ)_/ˉ數(文件大?。?if (message(╥_╥)Type === 1) { // 如果消息類(lèi)型為1,表示是收文文件(jian)信息,保存相關(guān)信息以供后(╥_╥)續使用 filename = filename; // 保存文件名到全局變量中 downloadUrl = URL.createObjectURL(new Blob([event.data])); // 創(chuàng )建下載鏈接的URL(暫時(shí)用整個(gè)事件數據作為Blob) downloadAnchorElement = document.createElement('a'); // 創(chuàng )建下載鏈接的錨元素(a標簽) downloadAnchorElement.href = downloadUrl; // 設置下載鏈接的URL屬性為之前創(chuàng )建的URL downloadAnchorElement.download = filename; // 設置下載鏈接的文件名為之前保存的文件名 document.body.appendChild(downloadAnchorElement); // 將下載鏈接添加到頁(yè)面中,但不立即觸發(fā)點(diǎn)擊事件(避免提前下載) } else if (messageTypヽ(′ー`)ノe === 2) { // 如果消息類(lèi)型為??2,表示是文件內容,將內容添加到Blob對象中以供后續下載使用 if (!downl??oadBlob) { // 如果還沒(méi)有創(chuàng )建Blob對??象,則先創(chuàng )建一個(gè)空的Blob對象作為初始值 downloadBlob = new Blob(); } else { // 如果已經(jīng)創(chuàng )建了Blob對象,則將(jiang)新收到的內容添加到已有的Blob對象中(追加方式) const contentBlob = new Blob([event.data]); // 根據事件數據創(chuàng )建一個(gè)新的Blob對象(內容部分) const finalBlob = new Blob([downloadBlob, contentBlob], { type: 'application/octetstream' }); // 根據已有的Blob對象和新的Blob對象創(chuàng )建一個(gè)新的Blob對象(合并方式) downloadBlob = finalBlo(◎_◎;)b??; // 更新下載??的文件對象為最終的Blob??對象(包含所有內容的Blob)?? } } else { // 如果消息類(lèi)型既不是1也不是2,則忽略該消息不進(jìn)??行處理(保留其他可能(neng)的消息類(lèi)型處理邏輯) co┐(′?`)┌nsole.war??n(未知的消息類(lèi)型:${ messageType}); } }; socket.onclose = () => { console.log('WebSocket連接已關(guān)閉'); if (downloadAnchorElement) { // 如果存在下載鏈接的錨元素,則將其從頁(yè)面中移除并觸發(fā)點(diǎn)擊事件以啟動(dòng)下載對話(huà)框(可選操作) 客服電話(huà)18966584448
Copyright ? 2012-2018 天津九安特機電工程有限公司 版權所有 備案號:
客服電話(huà)18181754170