Rumah hujung hadapan web tutorial js node静态文件服务器实例详解

node静态文件服务器实例详解

Mar 12, 2018 am 09:35 AM
node Contoh pelayan

本文主要和大家介绍了实战node静态文件服务器的示例,本文首先会列出它的功能然后再以代码的形式分享给大家,希望能帮助到大家。

支持功能:

  1. 读取静态文件

  2. 访问目录可以自动寻找下面的index.html文件, 如果没有index.html则列出文件列表

  3. MIME类型支持

  4. 缓存支持/控制

  5. 支持gzip压缩

  6. Range支持,断点续传

  7. 全局命令执行

  8. 子进程运行

1. 创建服务读取静态文件

首先引入http模块,创建一个服务器,并监听配置端口:

1

2

3

4

5

6

7

8

9

10

const http = require('http');

 

const server = http.createServer();

 

// 监听请求

server.on('request', request.bind(this));

 

server.listen(config.port, () => {

 console.log(`静态文件服务启动成功, 访问localhost:${config.port}`);

});

Salin selepas log masuk

写一个fn专门处理请求, 返回静态文件, url模块获取路径:

1

2

3

4

5

6

7

8

9

const url = require('url');

const fs = require('fs');

function request(req, res) {

const { pathname } = url.parse(req.url); // 访问路径

 

const filepath = path.join(config.root, pathname); // 文件路径

 

fs.createReadStream(filepath).pipe(res); // 读取文件,并响应

}

Salin selepas log masuk

支持寻找index.html:

1

2

3

4

5

6

7

8

9

10

11

if (pathname === '/') {

 const rootPath = path.join(config.root, 'index.html');

 try{

  const indexStat = fs.statSync(rootPath);

  if (indexStat) {

   filepath = rootPath;

  }

 } catch(e) {

   

 }

}

Salin selepas log masuk

访问目录时,列出文件目录:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

fs.stat(filepath, (err, stats) => {

if (err) {

 res.end('not found');

 return;

}

if (stats.isDirectory()) {

 let files = fs.readdirSync(filepath);

 files = files.map(file => ({

  name: file,

  url: path.join(pathname, file)

 }));

 let html = this.list()({

  title: pathname,

  files

 });

 res.setHeader('Content-Type', 'text/html');

 res.end(html);

}

}

Salin selepas log masuk

html模板:

1

2

3

4

function list() {

 let tmpl = fs.readFileSync(path.resolve(__dirname, 'template', 'list.html'), 'utf8');

 return handlebars.compile(tmpl);

}

Salin selepas log masuk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<!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>

<h1>hope-server静态文件服务器</h1>

<ul>

 {{#each files}}

 <li>

  <a href={{url}}>{{name}}</a>

 </li>

 {{/each}}

</ul>

</body>

</html>

Salin selepas log masuk

2.MIME类型支持

利用mime模块得到文件类型,并设置编码:

1

res.setHeader(&#39;Content-Type&#39;, mime.getType(filepath) + &#39;;charset=utf-8&#39;);

Salin selepas log masuk

3.缓存支持

http协议缓存:

Cache-Control: http1.1内容,告诉客户端如何缓存数据,以及规则

  1. private 客户端可以缓存

  2. public 客户端和代理服务器都可以缓存

  3. max-age=60 缓存内容将在60秒后失效

  4. no-cache 需要使用对比缓存验证数据,强制向源服务器再次验证

  5. no-store 所有内容都不会缓存,强制缓存和对比缓存都不会触发

Expires: http1.0内容,cache-control会覆盖,告诉客户端缓存什么时候过期

ETag: 内容的hash值 下一次客户端请求在请求头里添加if-none-match: etag值

Last-Modified: 最后的修改时间 下一次客户端请求在请求头里添加if-modified-since: Last-Modified值

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

handleCache(req, res, stats, hash) {

// 当资源过期时, 客户端发现上一次请求资源,服务器有发送Last-Modified, 则再次请求时带上if-modified-since

const ifModifiedSince = req.headers[&#39;if-modified-since&#39;];

// 服务器发送了etag,客户端再次请求时用If-None-Match字段来询问是否过期

const ifNoneMatch = req.headers[&#39;if-none-match&#39;];

// http1.1内容 max-age=30 为强行缓存30秒 30秒内再次请求则用缓存 private 仅客户端缓存,代理服务器不可缓存

res.setHeader(&#39;Cache-Control&#39;, &#39;private,max-age=30&#39;);

// http1.0内容 作用与Cache-Control一致 告诉客户端什么时间,资源过期 优先级低于Cache-Control

res.setHeader(&#39;Expires&#39;, new Date(Date.now() + 30 * 1000).toGMTString());

// 设置ETag 根据内容生成的hash

res.setHeader(&#39;ETag&#39;, hash);

// 设置Last-Modified 文件最后修改时间

const lastModified = stats.ctime.toGMTString();

res.setHeader(&#39;Last-Modified&#39;, lastModified);

 

// 判断ETag是否过期

if (ifNoneMatch && ifNoneMatch != hash) {

 return false;

}

// 判断文件最后修改时间

if (ifModifiedSince && ifModifiedSince != lastModified) {

 return false;

}

// 如果存在且相等,走缓存304

if (ifNoneMatch || ifModifiedSince) {

 res.writeHead(304);

 res.end();

 return true;

} else {

 return false;

}

}

Salin selepas log masuk

4.压缩

客户端发送内容,通过请求头里Accept-Encoding: gzip, deflate告诉服务器支持哪些压缩格式,服务器根据支持的压缩格式,压缩内容。如服务器不支持,则不压缩。

1

2

3

4

5

6

7

8

9

10

11

12

13

getEncoding(req, res) {

 const acceptEncoding = req.headers[&#39;accept-encoding&#39;];

 // gzip和deflate压缩

 if (/\bgzip\b/.test(acceptEncoding)) {

  res.setHeader(&#39;Content-Encoding&#39;, &#39;gzip&#39;);

  return zlib.createGzip();

 } else if (/\bdeflate\b/.test(acceptEncoding)) {

  res.setHeader(&#39;Content-Encoding&#39;, &#39;deflate&#39;);

  return zlib.createDeflate();

 } else {

  return null;

 }

}

Salin selepas log masuk

5.断点续传

服务器通过请求头中的Range: bytes=0-xxx来判断是否是做Range请求,如果这个值存在而且有效,则只发回请求的那部分文件内容,响应的状态码变成206,表示Partial Content,并设置Content-Range。如果无效,则返回416状态码,表明Request Range Not Satisfiable。如果不包含Range的请求头,则继续通过常规的方式响应。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

getStream(req, res, filepath, statObj) {

 let start = 0;

 let end = statObj.size - 1;

 const range = req.headers[&#39;range&#39;];

 if (range) {

  res.setHeader(&#39;Accept-Range&#39;, &#39;bytes&#39;);

  res.statusCode = 206;//返回整个内容的一块

  let result = range.match(/bytes=(\d*)-(\d*)/);

  if (result) {

   start = isNaN(result[1]) ? start : parseInt(result[1]);

   end = isNaN(result[2]) ? end : parseInt(result[2]) - 1;

  }

 }

 return fs.createReadStream(filepath, {

  start, end

 });

}

Salin selepas log masuk

6.全局命令执行

通过npm link实现

  1. 为npm包目录创建软链接,将其链到{prefix}/lib/node_modules/

  2. 为可执行文件(bin)创建软链接,将其链到{prefix}/bin/{name}

npm link命令通过链接目录和可执行文件,实现npm包命令的全局可执行。

package.json里面配置

1

2

3

4

5

{

bin: {

"hope-server": "bin/hope"

}

}

Salin selepas log masuk

在项目下面创建bin目录 hope文件, 利用yargs配置命令行传参数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

// 告诉电脑用node运行我的文件

#! /usr/bin/env node

 

const yargs = require(&#39;yargs&#39;);

const init = require(&#39;../src/index.js&#39;);

const argv = yargs.option(&#39;d&#39;, {

alias: &#39;root&#39;,

demand: &#39;false&#39;,

type: &#39;string&#39;,

default: process.cwd(),

description: &#39;静态文件根目录&#39;

}).option(&#39;o&#39;, {

alias: &#39;host&#39;,

demand: &#39;false&#39;,

default: &#39;localhost&#39;,

type: &#39;string&#39;,

description: &#39;配置监听的主机&#39;

}).option(&#39;p&#39;, {

alias: &#39;port&#39;,

demand: &#39;false&#39;,

type: &#39;number&#39;,

default: 8080,

description: &#39;配置端口号&#39;

}).option(&#39;c&#39;, {

alias: &#39;child&#39;,

demand: &#39;false&#39;,

type: &#39;boolean&#39;,

default: false,

description: &#39;是否子进程运行&#39;

})

.usage(&#39;hope-server [options]&#39;)

.example(

&#39;hope-server -d / -p 9090 -o localhost&#39;, &#39;在本机的9090端口上监听客户端的请求&#39;

).help(&#39;h&#39;).argv;

 

// 启动服务

init(argv);

Salin selepas log masuk

7.子进程运行

通过spawn实现

index.js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

const { spawn } = require(&#39;child_process&#39;);

 const Server = require(&#39;./hope&#39;);

 function init(argv) {

  // 如果配置为子进程开启服务

  if (argv.child) {

   //子进程启动服务

   const child = spawn(&#39;node&#39;, [&#39;hope.js&#39;, JSON.stringify(argv)], {

    cwd: __dirname,

    detached: true,

    stdio: &#39;inherit&#39;

   });

  

   //后台运行

   child.unref();

   //退出主线程,让子线程单独运行

   process.exit(0);

  } else {

   const server = new Server(argv);

   server.start();

  }

 }

  

 module.exports = init;

hope.js

 if (process.argv[2] && process.argv[2].startsWith(&#39;{&#39;)) {

 const argv = JSON.parse(process.argv[2]);

 const server = new Hope(argv);

 server.start();

 }

Salin selepas log masuk

8.源码及测试

源码地址: hope-server

1

npm install hope-server -g

Salin selepas log masuk

进入任意目录

1

hope-server

Salin selepas log masuk

相关推荐:

node静态文件服务器详解

使用nodejs、Python写的一个简易HTTP静态文件服务器

Node.js静态文件服务器改进版_node.js

Atas ialah kandungan terperinci node静态文件服务器实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk menyelesaikan masalah bahawa carian eMule tidak dapat menyambung ke pelayan Bagaimana untuk menyelesaikan masalah bahawa carian eMule tidak dapat menyambung ke pelayan Jan 25, 2024 pm 02:45 PM

Penyelesaian: 1. Semak tetapan eMule untuk memastikan anda telah memasukkan alamat pelayan dan nombor port yang betul 2. Semak sambungan rangkaian, pastikan komputer disambungkan ke Internet, dan tetapkan semula penghala; adalah dalam talian. Jika tetapan anda adalah Jika tiada masalah dengan sambungan rangkaian, anda perlu menyemak sama ada pelayan dalam talian 4. Kemas kini versi eMule, lawati tapak web rasmi eMule, dan muat turun versi terkini perisian eMule; 5. Dapatkan bantuan.

Penyelesaian kepada ketidakupayaan untuk menyambung ke pelayan RPC dan ketidakupayaan untuk memasuki desktop Penyelesaian kepada ketidakupayaan untuk menyambung ke pelayan RPC dan ketidakupayaan untuk memasuki desktop Feb 18, 2024 am 10:34 AM

Apakah yang perlu saya lakukan jika pelayan RPC tidak tersedia dan tidak boleh diakses pada desktop Dalam beberapa tahun kebelakangan ini, komputer dan Internet telah menembusi setiap sudut kehidupan kita. Sebagai teknologi untuk pengkomputeran berpusat dan perkongsian sumber, Panggilan Prosedur Jauh (RPC) memainkan peranan penting dalam komunikasi rangkaian. Walau bagaimanapun, kadangkala kita mungkin menghadapi situasi di mana pelayan RPC tidak tersedia, mengakibatkan ketidakupayaan untuk memasuki desktop. Artikel ini akan menerangkan beberapa kemungkinan punca masalah ini dan memberikan penyelesaian. Pertama, kita perlu memahami mengapa pelayan RPC tidak tersedia. Pelayan RPC ialah a

Penjelasan terperinci mengenai fius pemasangan CentOS dan pelayan pemasangan CentOS Penjelasan terperinci mengenai fius pemasangan CentOS dan pelayan pemasangan CentOS Feb 13, 2024 pm 08:40 PM

Sebagai pengguna LINUX, kami selalunya perlu memasang pelbagai perisian dan pelayan pada CentOS Artikel ini akan memperkenalkan secara terperinci cara memasang fius dan menyediakan pelayan pada CentOS untuk membantu anda menyelesaikan operasi yang berkaitan dengan lancar. CentOS installation fuseFuse ialah rangka kerja sistem fail ruang pengguna yang membenarkan pengguna yang tidak mempunyai hak untuk mengakses dan mengendalikan sistem fail melalui sistem fail tersuai Memasang fius pada CentOS adalah sangat mudah, cuma ikuti langkah berikut: 1. Buka terminal dan Log masuk sebagai pengguna akar. 2. Gunakan arahan berikut untuk memasang pakej fius: ```yuminstallfuse3. Sahkan gesaan semasa proses pemasangan dan masukkan `y` untuk meneruskan. 4. Pemasangan selesai

Bagaimana untuk mengkonfigurasi Dnsmasq sebagai pelayan geganti DHCP Bagaimana untuk mengkonfigurasi Dnsmasq sebagai pelayan geganti DHCP Mar 21, 2024 am 08:50 AM

Peranan geganti DHCP adalah untuk memajukan paket DHCP yang diterima ke pelayan DHCP lain pada rangkaian, walaupun kedua-dua pelayan berada pada subnet yang berbeza. Dengan menggunakan geganti DHCP, anda boleh menggunakan pelayan DHCP berpusat di pusat rangkaian dan menggunakannya untuk menetapkan alamat IP secara dinamik kepada semua subnet/VLAN rangkaian. Dnsmasq ialah pelayan protokol DNS dan DHCP yang biasa digunakan yang boleh dikonfigurasikan sebagai pelayan geganti DHCP untuk membantu mengurus konfigurasi hos dinamik dalam rangkaian. Dalam artikel ini, kami akan menunjukkan kepada anda cara mengkonfigurasi dnsmasq sebagai pelayan geganti DHCP. Topik Kandungan: Topologi Rangkaian Mengkonfigurasi Alamat IP Statik pada Geganti DHCP D pada Pelayan DHCP Berpusat

Panduan Amalan Terbaik untuk Membina Pelayan Proksi IP dengan PHP Panduan Amalan Terbaik untuk Membina Pelayan Proksi IP dengan PHP Mar 11, 2024 am 08:36 AM

Dalam penghantaran data rangkaian, pelayan proksi IP memainkan peranan penting, membantu pengguna menyembunyikan alamat IP sebenar mereka, melindungi privasi dan meningkatkan kelajuan akses. Dalam artikel ini, kami akan memperkenalkan panduan amalan terbaik tentang cara membina pelayan proksi IP dengan PHP dan menyediakan contoh kod khusus. Apakah pelayan proksi IP? Pelayan proksi IP ialah pelayan perantaraan yang terletak di antara pengguna dan pelayan sasaran Ia bertindak sebagai stesen pemindahan antara pengguna dan pelayan sasaran, memajukan permintaan dan respons pengguna. Dengan menggunakan pelayan proksi IP

Apakah yang perlu saya lakukan jika saya tidak boleh memasuki permainan apabila pelayan epik berada di luar talian? Bagaimana untuk menyelesaikan masalah tidak dapat memasuki permainan apabila epik di luar talian Apakah yang perlu saya lakukan jika saya tidak boleh memasuki permainan apabila pelayan epik berada di luar talian? Bagaimana untuk menyelesaikan masalah tidak dapat memasuki permainan apabila epik di luar talian Mar 13, 2024 pm 04:40 PM

Apakah yang perlu saya lakukan jika saya tidak boleh memasuki permainan apabila pelayan epik berada di luar talian? Masalah ini mesti dihadapi oleh ramai rakan Apabila gesaan ini muncul, permainan yang tulen ini biasanya disebabkan oleh gangguan dari rangkaian dan perisian keselamatan Jadi bagaimana ia harus diselesaikan Saya ingin berkongsi penyelesaian dengan anda Saya harap tutorial perisian hari ini dapat membantu anda menyelesaikan masalah. Perkara yang perlu dilakukan jika pelayan epik tidak boleh memasuki permainan apabila ia di luar talian: 1. Ia mungkin diganggu oleh perisian keselamatan Tutup platform permainan dan perisian keselamatan dan kemudian mulakan semula. 2. Yang kedua ialah rangkaian berubah-ubah terlalu banyak Cuba mulakan semula penghala untuk melihat jika keadaannya OK, anda boleh cuba menggunakan rangkaian mudah alih 5g untuk beroperasi. 3. Kemudian mungkin ada lagi

PI Node Teaching: Apakah nod pi? Bagaimana cara memasang dan menyediakan nod pi? PI Node Teaching: Apakah nod pi? Bagaimana cara memasang dan menyediakan nod pi? Mar 05, 2025 pm 05:57 PM

Penjelasan dan Panduan Pemasangan Terperinci untuk Pinetwork Nodes Artikel ini akan memperkenalkan ekosistem pinetwork secara terperinci - nod pi, peranan utama dalam ekosistem pinetwork, dan menyediakan langkah -langkah lengkap untuk pemasangan dan konfigurasi. Selepas pelancaran Rangkaian Ujian Blockchain Pinetwork, nod PI telah menjadi bahagian penting dari banyak perintis yang aktif mengambil bahagian dalam ujian, bersiap sedia untuk pelepasan rangkaian utama yang akan datang. Jika anda tidak tahu kerja pinet, sila rujuk apa itu picoin? Berapakah harga untuk penyenaraian? Penggunaan PI, perlombongan dan analisis keselamatan. Apa itu Pinetwork? Projek Pinetwork bermula pada tahun 2019 dan memiliki syiling pi cryptocurrency eksklusifnya. Projek ini bertujuan untuk mewujudkan satu yang semua orang boleh mengambil bahagian

Bagaimana untuk memasang sambungan PHP FFmpeg pada pelayan? Bagaimana untuk memasang sambungan PHP FFmpeg pada pelayan? Mar 28, 2024 pm 02:39 PM

Bagaimana untuk memasang sambungan PHPFFmpeg pada pelayan? Memasang sambungan PHPFFmpeg pada pelayan boleh membantu kami memproses fail audio dan video dalam projek PHP dan melaksanakan fungsi seperti pengekodan, penyahkodan, penyuntingan dan pemprosesan fail audio dan video. Artikel ini akan memperkenalkan cara memasang sambungan PHPFFmpeg pada pelayan, serta contoh kod tertentu. Pertama, kita perlu memastikan bahawa PHP dan FFmpeg dipasang pada pelayan. Jika FFmpeg tidak dipasang, anda boleh mengikuti langkah di bawah untuk memasang FFmpe

See all articles