Node.js 实现简易 Web 服务器:服务端渲染与静态资源处理
本文介绍如何利用 Node.js 的 http、fs 和 path 模块,结合 art-template 模板引擎,构建一个具备服务端渲染能力的简易 Web 服务器。文章对比了服务端与客户端渲染对 SEO 的影响,并通过京东案例说明混合渲染策略,最后提供完整的 Node.js 代码实现静态目录浏览与 HTML 渲染功能。
服务端渲染与客户端渲染的区别
本示例基于服务端渲染技术展开。服务端渲染的核心在于服务器端使用模板引擎生成 HTML。为了厘清概念,首先需要简要区分服务端渲染与客户端渲染的差异。
服务端渲染与客户端渲染的主要区别如下:
- 纯客户端渲染不利于搜索引擎优化(SEO)。
- 服务端渲染生成的 HTML 可直接被爬虫抓取,而客户端异步渲染(如 AJAX 加载内容)往往难以被爬虫识别和索引。
- 实际生产中,大多数网站并非采用纯异步或纯服务端渲染,而是将两者结合使用。
- 以京东为例,其商品列表采用服务端渲染,主要目的是提升 SEO 效果,确保内容能被搜索引擎及爬虫有效抓取。
- 而京东的商品评论列表为了优化用户体验,且对 SEO 依赖较低,因此采用客户端渲染方式。
判断页面采用服务端渲染还是客户端渲染的方法如下:
具体操作步骤为:
- 访问目标页面(此处以京东为例)。
- 进入任意商品详情页,复制商品标题文字。
- 在页面任意位置点击鼠标右键,选择“查看网页源代码”。
- 在源代码界面按下 Ctrl + F 快捷键,将复制的商品标题粘贴至搜索框。
- 若能在源代码中搜索到该内容,说明为服务端渲染;若搜索不到,则通常为客户端渲染。
art-template 模板引擎安装与使用
接下来介绍模板引擎 art-template 的使用:
- 安装步骤:在目标目录下打开命令行工具,执行命令 npm install art-template。执行成功后会自动生成 node_modules 目录(前提是系统已安装 Node.js 环境)。
- 在需要使用模板引擎的文件模块中加载 art-template:
- const template = require('art-template');
- 加载后即可使用。官方文档地址为:https://aui.github.io/art-template/zh-cn/docs/index.html
Node.js 实现简易 Web 服务器
以下是使用 Node.js 实现 Apache 部分核心功能的具体方案:
本例主要涉及以下 Node.js API:
基于 http 模块:
- createServer():用于创建服务器实例。
- on():用于监听事件,处理请求与响应,包括接收请求、处理逻辑及发送响应等数据服务。
- listen():用于绑定端口号并启动服务器。
基于 fs(文件系统)模块:
- readFile():用于读取文件,参数一为文件路径,参数二为回调函数。
- readdir():用于读取目录内容,参数一为目录路径,参数二为回调函数。
基于 path(路径)模块:
- extname():用于获取文件后缀名。
- 在项目任意位置创建一个名为 www 的文件夹(名称可自定义):

编写对应的 HTML 模板文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Index of / {{title}}</title>
</head>
<body>
<h1>Index of / {{title}}</h1>
<ul>
<li><a href="/" rel="external nofollow" > Parent Directory</a></li>
{{each files}}
<li><a href="/{{ $value }}" rel="external nofollow" >{{ $value }}/</a></li>
{{/each}}
</ul>
</body>
</html>
编写 Node.js 服务端代码:
const http = require('http');
const fs = require('fs');
const template = require('art-template');
const path = require('path');
const port = 5000;
const server = http.createServer();
server.on('request', (request, response) => {
let url = request.url;
let wwwDir = 'D:/www';
fs.readFile('./template.html', (error, data) => {
if (error) {
return response.end('404 Not Found');
}
// 1.如何得到 wwwDir 目录列表中的文件名和目录名
// fs.readdir
// 2.如何将得到的文件名和目录名替换到 template.html 中
// 2.1 在 template.html 中需要替换的位置预留一个特殊的标记
// 2.2 根据 files 生成需要的 HTML 内容
// 模板引擎
if (url !== '/') {
wwwDir += url;
}
let fileEnd = path.extname(wwwDir);
/**
* 如果是文件,则访问该文件
* 如果是文件夹,则访问里面的内容
*/
if (fileEnd !== '') {
fs.readFile(wwwDir, (error, data) => {
if (error) {
return response.end('404 Not Found');
}
// 获取文件后缀名(具体问题具体分析,这里我只设置 .txt 文件的 编码类型)
if (fileEnd === '.txt') {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
}
if (fileEnd === '.jpg') {
response.setHeader('Content-Type', 'image/jpeg');
}
if (fileEnd === '.mp4') {
response.setHeader('Content-Type', 'video/mpeg4');
}
response.end(data);
});
} else {
console.log(wwwDir);
fs.readdir(wwwDir, (error, files) => {
if (error) {
return response.end('Can not find this dir');
}
console.log(files);
// files: [ 'a.txt', 'apple', 'images', 'index.html', 'static', 'videos' ]
let htmlStr = template.render(data.toString(), {
title: wwwDir,
files: files,
});
// 3.发送响应数据
response.end(htmlStr);
});
}
});
});
server.listen(port, () => {
console.log(`服务器已经开启,您可以通过 http://127.0.0.1:${port} 访问....`);
});
总结
以上介绍了使用 Node.js 模拟 Apache 部分功能的方法,希望能对大家有所帮助。如有疑问欢迎留言,小编会及时回复!
Node.js 安装配置与第一个 HTTP 服务器编写
2026-11-05 11:41:40
怎么使用 nvm 管理并平滑升级 Node.js 版本
2026-11-04 23:15:07
Node.js 怎么使用 zlib 模块解压 gzip 和 deflate
2026-11-03 23:40:50
直接覆盖安装还是用版本管理器?Node.js 升级方式对比
2026-11-03 22:59:07
Express.js 是什么:Node.js Web 框架核心概念与适用场景
2026-11-03 20:00:12
