【问题标题】:Render raw HTML渲染原始 HTML
【发布时间】:2012-12-16 10:57:42
【问题描述】:

我想使用 Express 3 渲染原始的 .html 页面,如下所示:

server.get('/', function(req, res) {
    res.render('login.html');
}

这就是我配置服务器以呈现原始 HTML 页面的方式(灵感来自 this outdated question):

server
    .set('view options', {layout: false})
    .set('views', './../')
    .engine('html', function(str, options) {
        return function(locals) {
             return str;
        };
    });

不幸的是,使用此配置页面会挂起并且永远不会正确呈现。我做错了什么?如何在没有 Jade 和 EJS 等精美渲染引擎的情况下使用 Express 3 渲染原始 HTLM?

【问题讨论】:

  • 决定通过 Nodejs 提供静态 HTML 的动机是什么?从更广泛的背景来看,这似乎是一个次优的解决方案。
  • 这是一个非常简单的页面。例如,使用 Jade 的开销是不值得的。
  • 好的,假设在现有的高流量 Node 应用程序中有一个受到重创的静态页面,不需要共享模板。即便如此,这对我来说似乎编码太多了,编码意味着开发成本 + 测试 + 维护。我个人只是在响应中设置长缓存标头,让 Nginx/Apache 从缓存中提供内容。这样您就不需要自定义代码并且模板生成开销变得无关紧要。
  • 它实际上是使用 JavaScript 在客户端填充的静态 HTML 页面。人口信息由 Node.JS 实时生成。我不会离开 Node.JS。
  • 不建议您放弃 Node,我可以从您的回复中假设您没有在 Web 服务器后面运行 Node 吗?这是否意味着您需要直接访问 websocket?

标签: javascript node.js express


【解决方案1】:

您可以使用 res.sendFile() 发送文件。 您可以将所有 html 文件保存在 views 文件夹中,并可以在 options 变量中设置它的路径。

app.get('/', (req, res)=>{
    var options = {  root: __dirname + '/../views/' };
      var fileName = 'index.html';
      res.sendFile(fileName, options);
});

【讨论】:

    【解决方案2】:

    我认为你想说的是: 我怎样才能提供静态 html 文件,对吧?

    让我们开始吧。

    首先,我自己项目中的一些代码:

    app.configure(function() {
        app.use(express.static(__dirname + '/public'));
    });
    

    这意味着在我的应用文件夹中有一个名为 public 的文件夹。我所有的静态内容,例如 css、js 甚至 html 页面都在这里。

    要实际发送静态 html 页面,只需将其添加到您的应用文件中

    app.get('/', function(req, res) {
      res.sendFile(__dirname + '/public/layout.html');
    });
    

    因此,如果您有一个名为 xyz.com 的域;每当有人去那里时,他们都会在浏览器中看到 layout.html。

    编辑

    如果您使用的是 express 4,情况会有所不同。 路由和中间件的执行顺序与它们的放置顺序完全相同。

    一个很好的技术是将静态文件服务代码放在所有标准路由之后。 像这样:

    // All standard routes are above here
    app.post('/posts', handler.POST.getPosts);
    
    // Serve static files
    app.use(express.static('./public'));
    

    这非常重要,因为它可能会消除代码中的瓶颈。看看这个stackoverflow answer(他第一次谈到优化)

    express 4.0 的另一个主要变化是您不需要使用 app.configure()

    【讨论】:

    • 像魅力一样工作 - 在我的情况下,我使用的是相对路径并最终得到了一个 403,所以使用:res.sendfile(path.resolve('../path/to/index.html'));
    • 很抱歉提出这么旧的帖子 - 但sendfile 是否缓存内容?还是它在发送文件之前实际读取了文件?
    • @Martol1ni 我不太确定。在我的测试中,我更改了单个 html 文件的内容,并且 express 能够提供更新的副本,因此我认为它默认不会缓存。但是,我认为您正在寻找这个:github.com/isaacs/st
    • 使用 sendFile 代替现在已弃用的 sendfile
    【解决方案3】:
    app.get('/', function(req, res) {
      returnHtml(res, 'index');
    });
    
    function returnHtml(res, name) {
      res.sendFile(__dirname + '/' + name + '.html');
    }
    

    然后将你的 index.html 放到你的根页面,当然你可以创建一个 /views 文件夹并扩展 returnHtml() 函数。

    【讨论】:

      【解决方案4】:

      多年后,一个新的答案出现了。

      其实这个方法就像skypecakess answer;

      var fs = require('fs');
      
      app.get('/', function(req, res, next) {
          var html = fs.readFileSync('./html/login.html', 'utf8')
          res.send(html)
      })
      

      就是这样……

      如果使用 EJS 或 Jade,也可以使用以下代码:

      var fs = require('fs');
      
      app.get('/', function(req, res, next) {
          var html = fs.readFileSync('./html/login.html', 'utf8')
          res.render('login', { html: html })
      })
      

      views/login.ejs文件只包含以下代码:

      <%- locals.html %>
      

      【讨论】:

        【解决方案5】:

        我想这样做是因为我正在创建一个我不想绑定到视图引擎的样板 NodeJS 服务器。为此,拥有一个简单地返回 (html) 文件内容的占位符渲染引擎是很有用的。

        这是我想出的:

        //htmlrenderer.js
        
        'use strict';
        
        var fs = require('fs'); // for reading files from the file system
        
        exports.renderHtml = function (filePath, options, callback) { // define the template engine
            fs.readFile(filePath, function (err, content) {
                if (err) return callback(new Error(err));
                var rendered = content.toString();
                // Do any processing here...
                return callback(null, rendered);
            });
        };
        

        使用它:

        app.engine('html', htmlRenderer.renderHtml);
        app.set('view engine', 'html');
        

        来源:http://expressjs.com/en/advanced/developing-template-engines.html

        欢迎评论和建设性反馈!

        【讨论】:

          【解决方案6】:

          首先,您犯的错误是尝试使用 express 2.x 代码 sn-p 在 express 3.0 中呈现原始 HTML。从 express 3.0 开始,只会将文件路径而不是文件内容传递给查看引擎。

          提出解决方案,

          创建一个简单的视图引擎

          var fs = require('fs'); 
          
          function rawHtmlViewEngine(filename, options, callback) {
              fs.readFile(filename, 'utf8', function(err, str){
                  if(err) return callback(err);
          
                  /*
                   * if required, you could write your own 
                   * custom view file processing logic here
                   */
          
                  callback(null, str);
              }); 
          }
          

          这样使用

          server.engine('html', rawHtmlViewEngine)
          server.set('views', './folder');
          server.set('view engine', 'html');
          


          参考

          官方 express 2.x 到 3.x 迁移指南

          请参阅此网址中的“模板引擎集成”部分 https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x

          【讨论】:

            【解决方案7】:

            您可以使用以下代码快速呈现 .html 页面:-

            var app = express();
            
            app.engine('html', ejs.__express);
            

            在渲染时,您可以使用以下代码:-

            response.render('templates.html',{title:"my home page"});
            

            【讨论】:

              【解决方案8】:

              全新安装最新版 Express 后

              express the_app_name
              

              创建一个包含 app.js 的框架目录。

              app.js 中有一行写着:

                app.use(express.static(path.join(__dirname, 'public')));
              

              因此,一个名为 public 的文件夹是魔法发生的地方...

              然后通过以这种方式建模的函数完成路由:

              app.get('/', function(req,res) {
                    res.sendfile('public/name_of_static_file.extension');
                  });
              

              *示例:* 公共文件夹中的 index.html 在由以下行调用时提供:

                 app.get('/', function(req,res) {
                res.sendfile('public/index.html');
              });
              

              就资产而言: 确保从相对于 public 文件夹的文件夹中调用 css 和 javascript 文件。

              vanilla Express 安装将有 stylesheetsjavascriptsimages 用于启动文件夹。因此,请确保脚本和 css 表在 index.html 中具有正确的路径:

              例子:

              <link href="stylesheets/bootstrap.css" rel="stylesheet">
              

              <script src="javascripts/jquery.js"></script>
              

              【讨论】:

                【解决方案9】:

                正如文档所说:'Express 期望:(路径,选项,回调)' app.engin(...) 中的格式函数。

                因此您可以编写如下代码(为简单起见,但它可以工作):

                server
                .set('view options', {layout: false})
                .set('views', './../')
                .engine('html', function(path, options, cb) {
                    fs.readFile(path, 'utf-8', cb);
                });
                

                当然就像 2# & 3# 说的,你应该使用 express.static() 进行静态文件传输;上面的代码不适合生产

                【讨论】:

                  【解决方案10】:

                  如果您实际上不需要向模板中注入数据,express 中最简单的解决方案是使用静态文件服务器 (express.static())。

                  但是,如果您仍想手动连接到页面的路由(例如,您的示例映射 '/' 到 'login.html'),您可以尝试 res.sendFile() 发送您的 html 文档:

                  http://expressjs.com/api.html#res.sendfile

                  【讨论】:

                  • res.sendFile() 确实发送了 html,但不是所有相关的 CSS、JS 等。它似乎不适合手动路由。
                  • 为了让 css、js 等发送过来,最简单的机制是使用 express.static() 服务它们...实际上是相反的原因,因为 sendFile() 是手动路由,而 @ 987654327@ 将自动提供静态页面。
                  • @Randomblue 查看我处理css和javascript的答案,以免你想要一大堆404
                  • 为了记录,它是带有小写F的sendfile。奇怪的是它不是驼峰式的,但就是这样。
                  【解决方案11】:

                  您是否尝试过使用 fs 模块?

                  server.get('/', function(req, res) {
                      fs.readFile('index.html', function(err, page) {
                          res.writeHead(200, {'Content-Type': 'text/html'});
                          res.write(page);
                          res.end();
                      });
                  }
                  

                  【讨论】:

                  • 显然这不是生产就绪的,因为它不缓存结果。
                  • Randomblue,这对您来说应该不是问题,因为您正在提供静态文件,因此 (a) 在生产中静态内容的缓存应该由您的 Web 服务器而不是您的应用程序服务器来处理,并且 ( b)您提供的静态文件未处理模板,因此性能损失远低于正常情况
                  猜你喜欢
                  • 1970-01-01
                  • 2022-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-10-31
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多