Node.js 实现简易 Web 服务器:服务端渲染与静态资源处理

作者:星河

时间:2026-10-23

浏览:104

本文介绍如何利用 Node.js 的 http、fs 和 path 模块,结合 art-template 模板引擎,构建一个具备服务端渲染能力的简易 Web 服务器。文章对比了服务端与客户端渲染对 SEO 的影响,并通过京东案例说明混合渲染策略,最后提供完整的 Node.js 代码实现静态目录浏览与 HTML 渲染功能。

文章目录

服务端渲染与客户端渲染的区别

本示例基于服务端渲染技术展开。服务端渲染的核心在于服务器端使用模板引擎生成 HTML。为了厘清概念,首先需要简要区分服务端渲染与客户端渲染的差异。

服务端渲染与客户端渲染的主要区别如下:

  • 纯客户端渲染不利于搜索引擎优化(SEO)。
  • 服务端渲染生成的 HTML 可直接被爬虫抓取,而客户端异步渲染(如 AJAX 加载内容)往往难以被爬虫识别和索引。
  • 实际生产中,大多数网站并非采用纯异步或纯服务端渲染,而是将两者结合使用。
  • 以京东为例,其商品列表采用服务端渲染,主要目的是提升 SEO 效果,确保内容能被搜索引擎及爬虫有效抓取。
  • 而京东的商品评论列表为了优化用户体验,且对 SEO 依赖较低,因此采用客户端渲染方式。

判断页面采用服务端渲染还是客户端渲染的方法如下:

具体操作步骤为:

  1. 访问目标页面(此处以京东为例)。
  2. 进入任意商品详情页,复制商品标题文字。
  3. 在页面任意位置点击鼠标右键,选择“查看网页源代码”。
  4. 在源代码界面按下 Ctrl + F 快捷键,将复制的商品标题粘贴至搜索框。
  5. 若能在源代码中搜索到该内容,说明为服务端渲染;若搜索不到,则通常为客户端渲染。

art-template 模板引擎安装与使用

接下来介绍模板引擎 art-template 的使用:

  1. 安装步骤:在目标目录下打开命令行工具,执行命令 npm install art-template。执行成功后会自动生成 node_modules 目录(前提是系统已安装 Node.js 环境)。
  2. 在需要使用模板引擎的文件模块中加载 art-template:
  3. const template = require('art-template');
  4. 加载后即可使用。官方文档地址为: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 部分功能的方法,希望能对大家有所帮助。如有疑问欢迎留言,小编会及时回复!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章