Nodejs如何实现server side include功能?

发布于 1周前 作者 vueper 来自 nodejs/Nestjs

Nodejs如何实现server side include功能?

最近用node.js+express开发的时候,遇到一个问题需要实现server side include的功能,搜索了半天没有找到合适的解决方案,express 对于include的代码默认不处理,直接输出,没办法执行include的内容,我后来试着尝试nginx的反向代理一下,问题居然解决了。 nginx 开启ssi 配置ssi

主要是三个参数,ssi,ssi_silent_errors和ssi_types,均可以放在http,server和location的作用域下。

ssi on 开启ssi支持,默认是off

ssi_silent_errors on 默认值是off,开启后在处理SSI文件出错时不输出错误提示:"[an error occurred while processing the directive] "

ssi_types 默认是ssi_types text/html,所以如果需要htm和html支持,则不需要设置这句,如果需要shtml支持,则需要设置:ssi_types text/shtml

SSI的格式: < !–#include file=“bottom.htm”–> 或 < !–#include virtual="/hx/bottom.htm"–> 路径是相对server中root根目录。

更多请参见官方文档:http://wiki.nginx.org/NginxChsHttpSsiModule 关于nginx反向代理的问题可以问一下度娘,这里就不多解释了


5 回复

Node.js 如何实现 Server Side Include 功能

在使用 Node.js 和 Express 开发时,你可能会遇到需要实现类似于 Nginx 的 Server Side Include (SSI) 功能的需求。Nginx 提供了一种简单的方式来处理 SSI,但如果你正在使用 Node.js,你可以通过编写自定义中间件来实现这一功能。

什么是 Server Side Include (SSI)?

Server Side Include 是一种服务器端技术,允许你在 HTML 文件中嵌入其他文件。例如,你可以在一个 HTML 文件中包含页脚、头部或其他部分。

实现 SSI 的步骤

  1. 安装必要的依赖: 首先,你需要安装 express 框架。如果你还没有安装,可以通过以下命令安装:

    npm install express
  2. 创建基本的 Express 应用:

    创建一个简单的 Express 应用,并添加一个中间件来处理 SSI。

  3. 实现 SSI 中间件:

    下面是一个简单的 SSI 处理中间件的实现:

    const express = require('express');
    const fs = require('fs');
    const path = require('path');
    
    const app = express();
    
    // SSI middleware
    function ssiMiddleware(req, res, next) {
      const originalSend = res.send;
      res.send = function(content) {
        if (typeof content === 'string') {
          let result = content;
          const regex = /<!--\s*#include\s+(virtual|file)="([^"]+)"\s*-->/g;
    
          result = result.replace(regex, (match, p1, p2) => {
            const filePath = p1 === 'file' ? path.join(path.dirname(req.path), p2) : path.join(req.app.get('views'), p2);
            try {
              return fs.readFileSync(filePath, 'utf8');
            } catch (err) {
              console.error(`Error including file: ${err.message}`);
              return match;
            }
          });
    
          originalSend.call(this, result);
        } else {
          originalSend.apply(this, arguments);
        }
      };
      next();
    }
    
    app.use(ssiMiddleware);
    
    // 设置视图引擎和静态文件目录
    app.set('views', './views');
    app.use(express.static('public'));
    
    // 示例路由
    app.get('/', (req, res) => {
      res.render('index', { title: 'Home Page' });
    });
    
    app.listen(3000, () => {
      console.log('App is running on http://localhost:3000');
    });
  4. HTML 文件中的 SSI 使用:

    在你的 HTML 文件中,你可以使用类似 Nginx 的语法来包含其他文件。例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title><%= title %></title>
    </head>
    <body>
      <!--#include file="header.html"-->
      <h1>Welcome to my site</h1>
      <!--#include file="footer.html"-->
    </body>
    </html>
  5. 测试:

    启动应用并访问 http://localhost:3000,你应该能看到包含 header.htmlfooter.html 的完整页面。

通过这种方式,你可以在 Node.js 中实现类似于 Nginx 的 Server Side Include 功能。希望这对你有所帮助!


你说的view层的include吧 用模板引擎应该都支持的 我用的ejs+ejs-local 有include的功能

我也是用的 nginx 反向代理到 nodejs 服务器,但是 对于 include 还是原样输出了。请问你是怎么做到的?

哦哦,解决了,如你所说,关键代码在这里:ssi on;

在Node.js中实现类似Server Side Include (SSI) 的功能可以通过自定义中间件来实现。下面是一个简单的例子,演示如何使用Express框架实现这种功能。

首先,确保你已经安装了expressejs模板引擎(如果你选择使用EJS作为模板引擎的话):

npm install express ejs

接下来创建一个简单的Express应用,并添加一个中间件用于处理包含其他文件的功能:

const express = require('express');
const fs = require('fs');

const app = express();

// 设置视图引擎为EJS
app.set('view engine', 'ejs');

// 自定义中间件,处理SSI指令
function ssiMiddleware(req, res, next) {
    const originalSend = res.send;
    res.send = function(body) {
        let newBody = body;
        if (body.includes('<!--#include')) {
            const matches = body.match(/<!--#include\s+file=["']([^"']+)["']-->/g);
            if (matches) {
                matches.forEach(match => {
                    const filename = match.replace(/<!--#include\s+file=["']|["']-->/g, '');
                    const includedContent = fs.readFileSync(filename, 'utf-8');
                    newBody = newBody.replace(match, includedContent);
                });
            }
        }
        originalSend.call(this, newBody);
    };
    next();
}

app.use(ssiMiddleware);

app.get('/', (req, res) => {
    res.render('index', { title: 'Example Page' });
});

app.listen(3000, () => {
    console.log('App listening on port 3000!');
});

在这个例子中,我们创建了一个名为ssiMiddleware的中间件,它会检查响应体是否包含<!--#include file="..."-->这样的SSI指令。如果有,它将读取指定的文件并替换掉相应的指令。最后,我们将这个中间件添加到应用中,并通过EJS模板引擎渲染页面。

当然,这只是一个基本的实现,你可以根据自己的需求对其进行扩展,比如支持虚拟路径(virtual)等更复杂的场景。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!