実ノード静的ファイルサーバーのサンプルコード
この記事では主に実際のノード静的ファイル サーバーの例を紹介し、参考にしていきます。
この記事では主に実際のノードの静的ファイルサーバーの例を紹介し、詳細を共有します:
サポートされる機能:
静的ファイルを読み取る
ディレクトリにアクセスして、次のインデックスを自動的に検索します。 .html ファイル、index.html がない場合は、ファイルのリストをリストします
MIME タイプのサポート
キャッシュのサポート/制御
gzip 圧縮のサポート
範囲のサポート、ブレークポイントの再開
-
グローバル コマンドの実行
サブプロセスの実行
1. 静的ファイルを読み取るサービスを作成します
最初に http モジュールを導入し、サーバーを作成し、設定されたポートをリッスンします:
const http = require('http'); const server = http.createServer(); // 监听请求 server.on('request', request.bind(this)); server.listen(config.port, () => { console.log(`静态文件服务启动成功, 访问localhost:${config.port}`); });
fn を書き込みます特にリクエストを処理し、静的ファイルを返すために、URL モジュールはパスを取得します:
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); // 读取文件,并响应 }
index.html の検索をサポート:
if (pathname === '/') { const rootPath = path.join(config.root, 'index.html'); try{ const indexStat = fs.statSync(rootPath); if (indexStat) { filepath = rootPath; } } catch(e) { } }
ディレクトリにアクセスするとき、ファイル ディレクトリをリストします:
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); } }
html テンプレート:
function list() { let tmpl = fs.readFileSync(path.resolve(__dirname, 'template', 'list.html'), 'utf8'); return handlebars.compile(tmpl); }
<!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>
2。 MIME タイプのサポート
mime モジュールを使用してファイル タイプを取得し、エンコーディングを設定します:
res.setHeader('Content-Type', mime.getType(filepath) + ';charset=utf-8');
3. キャッシュ サポート
http プロトコル キャッシュ:
キャッシュ制御: http1.1 コンテンツ、クライアントにデータをキャッシュする方法を指示します。 、およびルール
プライベートクライアントはキャッシュできます
パブリッククライアントとプロキシサーバーの両方がキャッシュできます
max-age=60 キャッシュされたコンテンツは60秒後に期限切れになります
no-cache比較キャッシュを使用してデータを検証し、ソースサーバーに再度検証を強制します
no-store すべてのコンテンツはキャッシュされず、強制キャッシュも比較キャッシュもトリガーされません
有効期限: http1.0 コンテンツ、cache-control はそれをオーバーライドし、キャッシュがいつ期限切れになるかをクライアントに伝えます
ETag: コンテンツのハッシュ次のクライアントリクエストの場合、リクエストヘッダーに if-none-match: etag 値を追加します
Last-Modified: Last次のクライアント リクエストでは、if-modified-since: Last-Modified 値をリクエスト ヘッダーに追加します
handleCache(req, res, stats, hash) { // 当资源过期时, 客户端发现上一次请求资源,服务器有发送Last-Modified, 则再次请求时带上if-modified-since const ifModifiedSince = req.headers['if-modified-since']; // 服务器发送了etag,客户端再次请求时用If-None-Match字段来询问是否过期 const ifNoneMatch = req.headers['if-none-match']; // http1.1内容 max-age=30 为强行缓存30秒 30秒内再次请求则用缓存 private 仅客户端缓存,代理服务器不可缓存 res.setHeader('Cache-Control', 'private,max-age=30'); // http1.0内容 作用与Cache-Control一致 告诉客户端什么时间,资源过期 优先级低于Cache-Control res.setHeader('Expires', new Date(Date.now() + 30 * 1000).toGMTString()); // 设置ETag 根据内容生成的hash res.setHeader('ETag', hash); // 设置Last-Modified 文件最后修改时间 const lastModified = stats.ctime.toGMTString(); res.setHeader('Last-Modified', 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; } }
4. 圧縮
クライアントはコンテンツを送信し、リクエスト ヘッダーを通じてサポートされている圧縮形式をサーバーに伝えます。 -エンコーディング: gzip、deflate。サーバーはサポートされている圧縮形式に基づいてコンテンツを圧縮します。サーバーがサポートしていない場合、圧縮は実行されません。
getEncoding(req, res) { const acceptEncoding = req.headers['accept-encoding']; // gzip和deflate压缩 if (/\bgzip\b/.test(acceptEncoding)) { res.setHeader('Content-Encoding', 'gzip'); return zlib.createGzip(); } else if (/\bdeflate\b/.test(acceptEncoding)) { res.setHeader('Content-Encoding', 'deflate'); return zlib.createDeflate(); } else { return null; } }
5. 再開可能なアップロード
サーバーは、リクエスト ヘッダーの Range: bytes=0-xxx を使用して、Range リクエストを行っているかどうかを判断します。この値が存在し、有効である場合、ファイル コンテンツのリクエストされた部分のみが使用されます。応答ステータス コードは Partial Content を示す 206 になり、Content-Range が設定されます。無効な場合は、要求範囲が満たされないことを示す 416 ステータス コードが返されます。 Range リクエスト ヘッダーが含まれていない場合は、通常の方法で応答を続けます。
getStream(req, res, filepath, statObj) { let start = 0; let end = statObj.size - 1; const range = req.headers['range']; if (range) { res.setHeader('Accept-Range', 'bytes'); 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 }); }
6. グローバル コマンドの実行
npm リンクを通じて実行
npm パッケージ ディレクトリのソフト リンクを作成し、それを {prefix}/lib/node_modules/
実行可能ファイル (bin 用に作成) にリンクします。 ) ソフトリンク、{prefix}/bin/{name} にリンクします
npm link コマンドは、ディレクトリと実行可能ファイルをリンクすることで、npm package コマンドをグローバルに実行可能にします。
package.jsonの設定
{ bin: { "hope-server": "bin/hope" } }
プロジェクトの下にbinディレクトリhopeファイルを作成し、yargsを使用してパラメータを渡すようにコマンドラインを設定します
// 告诉电脑用node运行我的文件 #! /usr/bin/env node const yargs = require('yargs'); const init = require('../src/index.js'); const argv = yargs.option('d', { alias: 'root', demand: 'false', type: 'string', default: process.cwd(), description: '静态文件根目录' }).option('o', { alias: 'host', demand: 'false', default: 'localhost', type: 'string', description: '配置监听的主机' }).option('p', { alias: 'port', demand: 'false', type: 'number', default: 8080, description: '配置端口号' }).option('c', { alias: 'child', demand: 'false', type: 'boolean', default: false, description: '是否子进程运行' }) .usage('hope-server [options]') .example( 'hope-server -d / -p 9090 -o localhost', '在本机的9090端口上监听客户端的请求' ).help('h').argv; // 启动服务 init(argv);
7. spawn
index.jsconst { spawn } = require('child_process'); const Server = require('./hope'); function init(argv) { // 如果配置为子进程开启服务 if (argv.child) { //子进程启动服务 const child = spawn('node', ['hope.js', JSON.stringify(argv)], { cwd: __dirname, detached: true, stdio: 'inherit' }); //后台运行 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('{')) { const argv = JSON.parse(process.argv[2]); const server = new Hope(argv); server.start(); }
npm install hope-server -g
hope-server
JSで文字列連結関数を実装する方法(String.prototype.formatの拡張)
ES6を使用してWeakMapによるメモリリーク問題を解決する(詳細なチュートリアル)
実装方法JavaScript WeChat ID ランダム切り替えコードを使用して実行します (詳細なチュートリアル)
以上が実ノード静的ファイルサーバーのサンプルコードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











パソコン上のフォルダーを削除または解凍するときに、「エラー 0x80004005: 不明なエラー」というダイアログ ボックスが表示されることがあります。この状況はどう解決すればよいでしょうか?エラー コード 0x80004005 が表示される理由は実際にはたくさんありますが、そのほとんどはウイルスによって引き起こされます。DLL を再登録して問題を解決できます。以下では、エディターがエラー コード 0x80004005 の処理体験を説明します。 。一部のユーザーは、コンピュータの使用時にエラー コード 0X80004005 を表示されます。0x80004005 エラーは主に、コンピュータが特定のダイナミック リンク ライブラリ ファイルを正しく登録していないこと、またはファイアウォールがコンピュータとインターネット間の HTTPS 接続を許可していないことが原因で発生します。それでどうですか

DHCP リレーの役割は、2 つのサーバーが異なるサブネット上にある場合でも、受信した DHCP パケットをネットワーク上の別の DHCP サーバーに転送することです。 DHCP リレーを使用すると、ネットワーク センターに集中 DHCP サーバーを展開し、それを使用してすべてのネットワーク サブネット/VLAN に IP アドレスを動的に割り当てることができます。 Dnsmasq は、一般的に使用される DNS および DHCP プロトコル サーバーであり、ネットワーク内の動的ホスト構成の管理を支援する DHCP リレー サーバーとして構成できます。この記事では、dnsmasq を DHCP リレー サーバーとして構成する方法を説明します。コンテンツ トピック: ネットワーク トポロジ DHCP リレー上の静的 IP アドレスの構成 集中型 DHCP サーバー上の DHCP リレー D

ファイル パスは、ファイルまたはフォルダーを識別して検索するためにオペレーティング システムによって使用される文字列です。ファイル パスには、パスを区切る 2 つの一般的な記号、つまりスラッシュ (/) とバックスラッシュ () があります。これら 2 つのシンボルは、オペレーティング システムごとに異なる用途と意味を持ちます。スラッシュ (/) は、Unix および Linux システムで一般的に使用されるパス区切り文字です。これらのシステムでは、ファイル パスはルート ディレクトリ (/) から始まり、各ディレクトリ間はスラッシュで区切られます。たとえば、パス /home/user/Document

Quark Netdisk と Baidu Netdisk は現在、ファイルの保存に最も一般的に使用されている Netdisk ソフトウェアです。Quark Netdisk 内のファイルを Baidu Netdisk に保存したい場合は、どうすればよいですか?今回は、Quark Network Disk コンピュータから Baidu Network Disk にファイルを転送するためのチュートリアル手順を編集者がまとめたので、その操作方法を見てみましょう。 QuarkネットワークディスクファイルをBaiduネットワークディスクに保存するにはどうすればよいですか? Quark Network Disk から Baidu Network Disk にファイルを転送するには、まず Quark Network Disk から必要なファイルをダウンロードし、次に Baidu Network Disk クライアントでターゲット フォルダーを選択して開きます。次に、Quark Cloud Disk からダウンロードしたファイルを Baidu Cloud Disk クライアントによって開かれたフォルダーにドラッグ アンド ドロップするか、アップロード機能を使用してファイルを Baidu Cloud Disk に追加します。アップロードが完了したら、Baidu Cloud Disk にファイルが正常に転送されたかどうかを必ず確認してください。それでおしまい

ネットワーク データ転送において、IP プロキシ サーバーは重要な役割を果たし、ユーザーが実際の IP アドレスを隠し、プライバシーを保護し、アクセス速度を向上させるのに役立ちます。この記事では、PHP を使用して IP プロキシ サーバーを構築する方法に関するベスト プラクティス ガイドを紹介し、具体的なコード例を示します。 IPプロキシサーバーとは何ですか? IP プロキシ サーバーは、ユーザーとターゲット サーバーの間にある中間サーバーであり、ユーザーとターゲット サーバー間の転送ステーションとして機能し、ユーザーのリクエストと応答を転送します。 IPプロキシサーバーを使用する場合

最近、多くのネチズンが編集者に「hiberfil.sys ファイルとは何ですか?」と尋ねました。 hiberfil.sys は C ドライブのスペースを多く消費し、削除される可能性がありますか?エディターは、hiberfil.sys ファイルを削除できることを通知します。以下で詳細を見てみましょう。 hiberfil.sys は Windows システムの隠しファイルであり、システム休止状態ファイルでもあります。通常、C ドライブのルート ディレクトリに保存され、そのサイズはシステムに搭載されているメモリのサイズと同等です。このファイルはコンピュータが休止状態になっているときに使用され、リカバリ中に以前の状態にすばやく復元できるように、現在のシステムのメモリ データが含まれています。そのサイズはメモリ容量と等しいため、より多くのハードドライブスペースを占有する可能性があります。冬休み

Epic サーバーがオフラインのときにゲームに参加できない場合はどうすればよいですか?この問題は多くの友人が経験しているはずです。このプロンプトが表示されると、正規のゲームが起動できなくなります。この問題は通常、ネットワークやセキュリティ ソフトウェアからの干渉によって引き起こされます。では、どのように解決すればよいでしょうか?今回の編集者が説明します。解決策を皆さんと共有したいと思います。今日のソフトウェア チュートリアルが問題の解決に役立つことを願っています。オフライン時に epic サーバーがゲームに参加できない場合の対処方法: 1. セキュリティ ソフトウェアによって妨害されている可能性があります。ゲーム プラットフォームとセキュリティ ソフトウェアを閉じて、再起動します。 2. 2 つ目は、ネットワークの変動が大きすぎることです。ルーターを再起動して機能するかどうかを確認してください。状態に問題がない場合は、5G モバイル ネットワークを使用して動作を試みることができます。 3. それならもっとあるかもしれない

ピン張りのノードの詳細な説明とインストールガイドこの記事では、ピネットワークのエコシステムを詳細に紹介します - PIノードは、ピン系生態系における重要な役割であり、設置と構成の完全な手順を提供します。 Pinetworkブロックチェーンテストネットワークの発売後、PIノードは多くの先駆者の重要な部分になり、テストに積極的に参加し、今後のメインネットワークリリースの準備をしています。まだピン張りのものがわからない場合は、ピコインとは何かを参照してください。リストの価格はいくらですか? PIの使用、マイニング、セキュリティ分析。パインワークとは何ですか?ピン競技プロジェクトは2019年に開始され、独占的な暗号通貨PIコインを所有しています。このプロジェクトは、誰もが参加できるものを作成することを目指しています
