日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

node静态服务器tudo

發(fā)布時間:2023/12/16 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 node静态服务器tudo 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
實現(xiàn)以下功能
  • 讀取靜態(tài)文件或目錄
  • MIME類型支持
  • 緩存支持/控制
  • 支持gzip壓縮
  • 訪問目錄可以自動尋找下面的index.html文件
  • Range支持,斷點續(xù)傳
  • 圖片防盜鏈
  • 后臺運(yùn)行

基本功能讀取靜態(tài)文件

此功能分為兩部分:

* 1、返回文件調(diào)用fs建立可讀流讀取文件返回客戶端fs.createReadStream(filepath).pipe(res);* 2、返回目錄因為是要返回當(dāng)前請求路徑下的所有目錄,并且支持點擊進(jìn)入下一級,所有返回文件為html采用handlebars模板引擎編輯模板// 處理模板函數(shù)let list = function () {let template = fs.readFileSync(listTemplatePath, 'utf8');return handlebars.compile(template);}// template 文件<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>{{title}}</title></head><body><ul>{{#each files}}<li><a href={{url}}>{{name}}</a></li>{{/each}}</ul></body></html>// 讀取當(dāng)前路徑下的所有目錄let { promisify, inspect } = util;// 轉(zhuǎn)變fs.readdir 異步方法返回promiselet readdirPromise = promisify(fs.readdir);// 返回filepath下所有目錄let files = await readdirPromise(filepath)// 處理files為我們想要的數(shù)據(jù)files = files.map(file => ({name: file,url: path.join(pathname, file),}))// 最終返回客戶端的html// listlet html = this.list({title: pathname,files,});

MIME類型支持

res.setHeader('Content-Type', mime.getType(filepath));

緩存支持/控制

toCache (req, res, filepath, stat) {// 強(qiáng)制緩存res.setHeader('Cache-Control', 'private,max-age=60'); // http 1.1// private 客戶端可以緩存// public 客戶端和代理服務(wù)器都可以緩存// max-age=60 緩存內(nèi)容將在60秒后失效// no-cache 需要使用對比緩存驗證數(shù)據(jù),強(qiáng)制向源服務(wù)器再次驗證// no-store 所有內(nèi)容都不會緩存,強(qiáng)制緩存和對比緩存都不會觸發(fā) res.setHeader('Expires', new Date(Date.now() + 60 * 1000).toUTCString()); // http 1.0// 對比緩存// last-modifylet ifModifiedSince = req.headers['if-modified-since'];let lastModified = stat.ctime.toGMTString();// etaglet ifNoneMatch = req.headers['if-none-match'];let eTag = cypto.createHash('sha1').update(stat.ctime.toGMTString() + stat.size).digest('hex');if (ifModifiedSince || ifNoneMatch) {if (ifNoneMatch === eTag && lastModified === ifModifiedSince) {res.statusCode = 304;res.end('');return false;}if ((ifModifiedSince && lastModified === ifModifiedSince) || (ifNoneMatch && ifNoneMatch === eTag)) {res.statusCode = 304;res.end('');return false;}}res.setHeader('Last-Modified', lastModified);res.setHeader('ETag', eTag);return true;}

壓縮支持

async gzip(req, res, gzipInfo) {let encoding = req.headers['accept-encoding'];let gzipReg = /\bgzip\b/;let deflateReg = /\bdeflate\b/;let type, streamInfo; if (gzipReg.test(encoding)) {streamInfo = gzipInfo ? await gzipPromise(gzipInfo) : zlib.createGzip();type = 'gzip';} else if (deflateReg.test(encoding)) {streamInfo = gzipInfo ? await deflatePromise(gzipInfo) : zlib.createDeflate();type = 'deflate';}if (type) {res.setHeader('Content-Encoding', type);}return streamInfo;}

訪問目錄可以自動尋找下面的index.html文件

let indexFilepath = path.join(filepath, '/', 'index.html'); try {let statIndex = await statPromise(indexFilepath);if (statIndex) {// 返回 inde.html文件return this.sendFile(req, res, indexFilepath, stat);} } catch (e) {}

Range支持,斷點續(xù)傳

range (req, res, filepath, stat) {res.setHeader('Accept-Range', 'bytes'); // 通知客戶端支持獲取部分資源let range = req.headers['range']; // Range: bytes=0-xxxlet start = 0, end = stat.size;if (range) {let result = range.match(/bytes=(\d*)-(\d*)/);start = isNaN(result[1]) ? result[1] : start;end = isNaN(result[2]) ? result[2] : end;}return fs.createReadStream(filepath, {start,end,})}

圖片防盜鏈

notSteal (req, res) {console.log(path.join(process.cwd(), 'imgs/load.png'))let refer = req.headers['referer'] || req.headers['refer'];//如果說有refer的話,則表示是從HTML頁面中引用過來的if (refer) {let { host } = Url.parse(refer);if (host !== hostDomain) {// 返回默認(rèn)圖return fs.createReadStream(path.join(process.cwd(), 'imgs/load.png'));}} }

開啟子進(jìn)程運(yùn)行

let { spawn } = require('child_process'); let fs = require('fs');let serverPath = '../src/child.js'; let child = spawn('node', [serverPath], {detached: true,stdio: ['ignore', process.stdout, 'ignore'] })child.unref();
  • 功能尚不完善,之后會慢慢豐富!
  • 更多細(xì)節(jié)源碼請查看我的GitHub sevenStatic

參考

  • Node.js靜態(tài)文件服務(wù)器實戰(zhàn)

總結(jié)

以上是生活随笔為你收集整理的node静态服务器tudo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。