淺析Node.js實(shí)現(xiàn)HTTP文件下載
前言
HTTP實(shí)現(xiàn)文件下載時(shí),只要在服務(wù)器設(shè)置好相關(guān)響應(yīng)頭,并使用二進(jìn)制傳輸文件數(shù)據(jù)即可,而客戶(hù)端(瀏覽器)會(huì)根據(jù)響應(yīng)頭接收文件數(shù)據(jù)。而在Node.js中,設(shè)置好響應(yīng)頭后,讀取文件流,再使用“.pipe()”
方法將流轉(zhuǎn)接到響應(yīng)對(duì)象Response
就可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的文件下載服務(wù)器。
1. 文件下載介紹
HTTP基于請(qǐng)求頭和響應(yīng)頭實(shí)現(xiàn)狀態(tài)交互,在得到服務(wù)器正確響應(yīng)狀態(tài)后,而客戶(hù)端首先會(huì)解析響應(yīng)頭,并根據(jù)響應(yīng)頭來(lái)接收和展示數(shù)據(jù)(響應(yīng)體)。對(duì)于文件下載來(lái)說(shuō),其實(shí)現(xiàn)過(guò)程如下:
1.客戶(hù)端發(fā)起文件資源請(qǐng)求
2.服務(wù)器查找對(duì)應(yīng)文件,并設(shè)置”Content-Type
”、”Content-Disposition
”等響應(yīng)頭,分別用于表示文件的”MIME”類(lèi)型及文件描述
3.客戶(hù)端根據(jù)服務(wù)器返回的響應(yīng)頭解析和接收文件數(shù)據(jù)
需要設(shè)置的響應(yīng)頭
設(shè)置文件下載響應(yīng)頭時(shí),除了常用的HTTP響應(yīng)頭外,比較重要是還要設(shè)置以下兩個(gè)響應(yīng)頭:
Content-Type: application/octet-stream Content-Disposition: attachment; filename=MyFileName.ext
在上面的設(shè)置中,”Content-Type: application/octet-stream
”告訴瀏覽器這是一個(gè)二進(jìn)制文件,”Content-Disposition
”告訴瀏覽器這是一個(gè)需要下載的附件并告訴瀏覽器默認(rèn)的文件名。如果不添加”Content-Disposition
”響應(yīng)頭,瀏覽器可能會(huì)下載或顯示文件內(nèi)容,不同瀏覽器的處理有所不同。
2. Node.js文件下載服務(wù)器實(shí)現(xiàn)
接下來(lái)我們基于Express 框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單文件下載服務(wù)器,在這個(gè)服務(wù)器中主要包括兩個(gè)功能:服務(wù)器文件的瀏覽、文件的下載。
2.1 添加路由
創(chuàng)建Express應(yīng)用后,添加如下兩個(gè)路由:
router.get('/files', function(req, res, next) { // 顯示服務(wù)器文件 }); router.get('/file/:fileName', function(req, res, next) { // 實(shí)現(xiàn)文件下載 });
上面的添加的兩個(gè)路由分別用于:顯示服務(wù)器文件、實(shí)現(xiàn)文件下載。
2.2 顯示服務(wù)器文件
實(shí)現(xiàn)服務(wù)器文件的顯示,要通過(guò)”fs
”模塊讀取文件目錄并進(jìn)行文件/目錄檢查等。還需要使用”path”模塊處理文件路徑。首先引入這兩個(gè)模塊:
const fs = require('fs'); const path = require('path');
顯示服務(wù)器文件實(shí)現(xiàn)代碼如下:
router.get('/files', function(req, res, next) { // 顯示服務(wù)器文件 // 文件目錄 var filePath = path.join(__dirname, './'); fs.readdir(filePath, function(err, results){ if(err) throw err; if(results.length>0) { var files = []; results.forEach(function(file){ if(fs.statSync(path.join(filePath, file)).isFile()){ files.push(file); } }) res.render('files', {files:files}); } else { res.end('當(dāng)前目錄下沒(méi)有文件'); } }); });
上面代碼中,讀取目錄后通過(guò)視圖文件”files.ejs
”顯示可下載文件列表。其代碼如下:
<!DOCTYPE html> <html> <head> <title>下載文件選擇</title> </head> <body> <h1>請(qǐng)選擇下載文件:</h1> <% if(files.length>0) {%> <ul> <% files.forEach(function(file){ %> <li> <a href="/file/<%- file %>" target="_blank"><%- file %></a> </li> <%})%> </ul> <%} else {%> <p>沒(méi)有可下載文件…</p> <%}%> </body> </html>
2.3 實(shí)現(xiàn)文件下載
實(shí)現(xiàn)文件下載時(shí),可以先讀取文件到一個(gè)”Buffer
”中,再通過(guò)”res.send()”
或”res.end()”
方法發(fā)送文件數(shù)據(jù),也可以基于流(”Stream
”)實(shí)現(xiàn)文件數(shù)據(jù)的發(fā)送。使用”Stream
”實(shí)現(xiàn)文件下載時(shí),可以使用”fs.createReadStream()”
方法創(chuàng)建一個(gè)可讀流,而響應(yīng)對(duì)象Response
是一個(gè)可寫(xiě)流。這樣,只需要通過(guò)”.pipe()”
方法將文件流轉(zhuǎn)接到Response
響應(yīng)流中即可。
文件下載實(shí)現(xiàn)代碼如下:
router.get('/file/:fileName', function(req, res, next) { // 實(shí)現(xiàn)文件下載 var fileName = req.params.fileName; var filePath = path.join(__dirname, fileName); var stats = fs.statSync(filePath); if(stats.isFile()){ res.set({ 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename='+fileName, 'Content-Length': stats.size }); fs.createReadStream(filePath).pipe(res); } else { res.end(404); } });
總結(jié)
以上就是利用Node.js實(shí)現(xiàn)HTTP文件下載的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)Node.js有所幫助。
- Node.js的Express框架使用上手指南
- 從零開(kāi)始學(xué)習(xí)Node.js系列教程之基于connect和express框架的多頁(yè)面實(shí)現(xiàn)數(shù)學(xué)運(yùn)算示例
- node.js使用express框架進(jìn)行文件上傳詳解
- node.js express框架簡(jiǎn)介與實(shí)現(xiàn)
- Node.js + express實(shí)現(xiàn)上傳大文件的方法分析【圖片、文本文件】
- node.js(express)中使用Jcrop進(jìn)行圖片剪切上傳功能
- Node.js 使用request模塊下載文件的實(shí)例
- Node.JS段點(diǎn)續(xù)傳:Nginx配置文件分段下載功能的實(shí)現(xiàn)方法
- 基于nodejs+express4.X實(shí)現(xiàn)文件下載的實(shí)例代碼
- nodejs+express實(shí)現(xiàn)文件上傳下載管理網(wǎng)站
- 使用nodejs+express實(shí)現(xiàn)簡(jiǎn)單的文件上傳功能
- node.js express框架實(shí)現(xiàn)文件上傳與下載功能實(shí)例詳解
相關(guān)文章
node.js調(diào)用C++函數(shù)的方法示例
這篇文章主要介紹了node.js調(diào)用C++函數(shù)的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Node.js開(kāi)發(fā)靜態(tài)資源服務(wù)器
這篇文章主要為大家介紹了Node.js開(kāi)發(fā)靜態(tài)資源服務(wù)器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08NodeJS連接MySQL數(shù)據(jù)庫(kù)并進(jìn)行增刪改查操作詳解
本篇是使用NodeJS的模塊MySQL操作MySQL數(shù)據(jù)庫(kù)的基礎(chǔ)教程,連接MySQL數(shù)據(jù)庫(kù)并進(jìn)行增刪改查操作詳解,需要的朋友可以參考下2024-02-02Node.JS利用PhantomJs抓取網(wǎng)頁(yè)入門(mén)教程
現(xiàn)今,網(wǎng)頁(yè)抓取已經(jīng)是一種人所共知的技術(shù)了,然而依然存在著諸多復(fù)雜性,下面這篇文章主要給大家介紹了Node.JS利用PhantomJs抓取網(wǎng)頁(yè)的方法教程,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-05-05k8s node節(jié)點(diǎn)重新加入master集群的實(shí)現(xiàn)
這篇文章主要介紹了k8s node節(jié)點(diǎn)重新加入master集群的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02了不起的node.js讀書(shū)筆記之node的學(xué)習(xí)總結(jié)
這篇文章主要介紹了了不起的node.js讀書(shū)筆記之node的學(xué)習(xí)總結(jié),需要的朋友可以參考下2014-12-12NodeJS學(xué)習(xí)筆記之網(wǎng)絡(luò)編程
Node.js采用了Google Chrome瀏覽器的V8引擎,性能很好,同時(shí)還提供了很多系統(tǒng)級(jí)的API,如文件操作、網(wǎng)絡(luò)編程等。Node.js則是一個(gè)全面的后臺(tái)運(yùn)行時(shí),為Javascript提供了其他語(yǔ)言能夠?qū)崿F(xiàn)的許多功能。今天我們來(lái)看下Nodejs的網(wǎng)絡(luò)編程2014-08-08nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解
這篇文章主要為大家介紹了nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09