【问题标题】:Render basic HTML view?渲染基本的 HTML 视图?
【发布时间】:2011-05-30 14:21:36
【问题描述】:

我有一个基本的 node.js 应用程序,我正在尝试使用 Express 框架启动它。我有一个views 文件夹,其中有一个index.html 文件。但是我在加载网络浏览器时收到以下错误。

错误:找不到模块“html”

下面是我的代码。

var express = require('express');
var app = express.createServer();

app.use(express.staticProvider(__dirname + '/public'));

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

app.listen(8080, '127.0.0.1')

我在这里错过了什么?

【问题讨论】:

    标签: javascript html node.js mongodb express


    【解决方案1】:

    来自 Express.js 指南:View Rendering

    查看文件名采用Express.ENGINE 的形式,其中ENGINE 是所需模块的名称。 例如视图layout.ejs会告诉视图系统require('ejs'),正在加载的模块必须导出方法exports.render(str, options)以符合Express,但是@987654329 @ 可用于将引擎映射到文件扩展名,例如 foo.html 可以被玉器渲染。

    所以你要么创建自己的简单渲染器,要么只使用jade:

     app.register('.html', require('jade'));
    

    More 关于app.register

    注意,在 Express 3 中,这个方法被重命名为app.engine

    【讨论】:

    • 注意- app.register 在 Express 3 中已重命名为 app.engine。
    • 查看 Andrew Homeyer 的回答。这是实际的答案。
    • 从其他答案来看,对于 Express 4,我最终使用了 app.engine('.html', require('ejs').renderFile);
    • 在 express 4 中,你也可以使用:app.set('view engine', 'jade');
    【解决方案2】:

    您也可以阅读 HTML 文件并将其发送:

    app.get('/', (req, res) => {
        fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) => {
            res.send(text);
        });
    });
    

    【讨论】:

    • 这个解决方案很糟糕,因为没有缓存文件;每个请求都会读取它。
    • 手动缓存它可能很容易。只需将读取的文件存储为变量,如果该变量为空,则仅再次读取。您还可以使用 JS 对象并将各种文件存储在各种变量中,并带有时间戳。当然,它比大多数人所做的工作要多,但是对于刚接触节点的人来说,这很好。很容易理解
    • 哎呀。这违背了面向约定的流线型架构(如 MVC)的全部意义。
    • @MarcelFalliere 您假设他想要缓存文件,或者他不想使用自定义缓存解决方案。谢谢 keegan3d 的回答。
    • @MarcelFalliere 那么,什么是正确的解决方案?我看到其他需要新依赖项的答案。是否只需要提供 html 文件?
    【解决方案3】:

    试试这个。它对我有用。

    app.configure(function(){
    
      .....
    
      // disable layout
      app.set("view options", {layout: false});
    
      // make a custom html template
      app.register('.html', {
        compile: function(str, options){
          return function(locals){
            return str;
          };
        }
      });
    });
    
    ....
    
    app.get('/', function(req, res){
      res.render("index.html");
    });
    

    【讨论】:

    • 上面的确切配置有问题,所以我从“.html”中删除了点并添加了这个:app.set('view engine', 'html'); app.set('views', __dirname + '/views');完美渲染
    • 这有点奇怪...您应该将 html 作为静态文件提供。这也为您提供了更好的缓存的好处。创建自定义“html 编译器”似乎是错误的。如果您需要从路由中发送文件(您很少需要这样做),只需阅读并发送它。否则只需重定向到静态 html。
    • @Enyo 这个评论似乎很奇怪,考虑到如何做你所说的应该做的是被问到的问题,而你的答案就是去做。如何使用缓存提供静态 html?
    • 我在app.register 上看到一个错误。也许它在 express 3.0.0.rc3 中已被弃用? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
    • @enyo,您错过了流线型架构的要点。当模式是控制器/视图(或/处理器/视图,无论您的具体架构是什么)时,您都不能使用过时的扩展模型偏离该模式。您需要将 HTML 视为呈现的内容,就像其他所有内容一样。保持干燥,伙计。
    【解决方案4】:
    app.get('/', function (req, res) {
    res.sendfile(__dirname + '/public/index.html');
    });
    

    【讨论】:

    • sendfile 在生产模式下没有缓存,所以这不是一个好的解决方案。
    • @SeymourCakes 如果我错了请纠正我,但我认为 sendFile 现在支持缓存:devdocs.io/express/index#res.sendFile
    【解决方案5】:

    你可以让 Jade 包含一个纯 HTML 页面:

    在views/index.jade中

    include plain.html
    

    在views/plain.html中

    <!DOCTYPE html>
    ...
    

    而 app.js 仍然可以只渲染玉:

    res.render(index)
    

    【讨论】:

    • 请注意,我想要只提供一个 .html 文件,因为我的应用是单页的;)
    • 我们可以用这种方法包含多个 HTML/JS 页面吗?
    • 难道不应该只为 express 的初始测试而在没有翡翠模板的情况下呈现该 html 页面吗?
    • 那么我们是否必须为每个 HTML 文件创建一个翡翠模板?
    • 更多的是 hack 而不是解决方案。
    【解决方案6】:

    对于我的项目,我创建了这个结构:

    index.js
    css/
        reset.css
    html/
        index.html
    

    此代码为/ 请求提供index.html,为/css/reset.css 请求提供reset.css。很简单,最好的部分是它会自动添加缓存头

    var express = require('express'),
        server = express();
    
    server.configure(function () {
        server.use('/css', express.static(__dirname + '/css'));
        server.use(express.static(__dirname + '/html'));
    });
    
    server.listen(1337);
    

    【讨论】:

    • server.configure 已弃用,所以直接使用server.use
    【解决方案7】:

    我在express 3.Xnode 0.6.16 中也遇到了同样的问题。上面给出的解决方案不适用于最新版本express 3.x。他们删除了app.register 方法并添加了app.engine 方法。如果您尝试了上述解决方案,您最终可能会遇到以下错误。

    node.js:201
            throw e; // process.nextTick error, or 'error' event on first tick
                  ^
    TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
        at Function.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:37:5)
        at Function.configure (/home/user1/ArunKumar/firstExpress/node_modules/express/lib/application.js:399:61)
        at Object.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:22:5)
        at Module._compile (module.js:441:26)
        at Object..js (module.js:459:10)
        at Module.load (module.js:348:31)
        at Function._load (module.js:308:12)
        at Array.0 (module.js:479:10)
        at EventEmitter._tickCallback (node.js:192:40)
    

    摆脱错误信息。将以下行添加到您的 app.configure function

    app.engine('html', require('ejs').renderFile);
    

    注意:你必须安装ejs模板引擎

    npm install -g ejs
    

    例子:

    app.configure(function(){
    
      .....
    
      // disable layout
      app.set("view options", {layout: false});
    
      app.engine('html', require('ejs').renderFile);
    
    ....
    
    app.get('/', function(req, res){
      res.render("index.html");
    });
    

    注意: 最简单的解决方案是使用 ejs 模板作为视图引擎。在那里,您可以在 *.ejs 视图文件中编写原始 HTML。

    【讨论】:

    • 一定要全局安装ejs吗?
    • 它告诉我它找不到'index.html'文件
    【解决方案8】:

    其中许多答案已过时。

    使用 express 3.0.0 和 3.1.0,以下工作:

    app.set('views', __dirname + '/views');
    app.engine('html', require('ejs').renderFile);
    

    有关 express 3.4+ 的替代语法和注意事项,请参阅下面的 cmets:

    app.set('view engine', 'ejs');
    

    然后你可以这样做:

    app.get('/about', function (req, res)
    {
        res.render('about.html');
    });
    

    这假设您在views 子文件夹中有您的视图,并且您已经安装了ejs 节点模块。如果没有,请在 Node 控制台上运行以下命令:

    npm install ejs --save
    

    【讨论】:

    • 为什么 res.render 在这种情况下需要 .html 扩展名,但在默认情况下不需要使用 jam。使用样板代码,它只调用 res.render('index', { title: 'Express' });但在这里,它是: res.render('about.html');
    • @Transcendence,我不确定。也许您应该提出一个新问题。
    • 使用 Express 3.4.2:app.set('view engine', 'ejs');
    • 你应该使用命令'npm install ejs --save'来更新你的package.json
    • 为什么需要ejs?
    【解决方案9】:

    如果您不必使用 views 目录,只需将 html 文件移动到下面的 public 目录即可。

    然后,将此行添加到 app.configure 而不是“/views”。

    server.use(express.static(__dirname + '/public'));

    【讨论】:

      【解决方案10】:

      如果您使用的是 express@~3.0.0,请从您的示例中更改以下行:

      app.use(express.staticProvider(__dirname + '/public'));
      

      到这样的事情:

      app.set("view options", {layout: false});
      app.use(express.static(__dirname + '/public'));
      

      我按照express api page 中的描述制作了它,它就像魅力一样。通过该设置,您无需编写额外的代码,因此很容易用于您的微生产或测试。

      完整代码如下:

      var express = require('express');
      var app = express.createServer();
      
      app.set("view options", {layout: false});
      app.use(express.static(__dirname + '/public'));
      
      app.get('/', function(req, res) {
          res.render('index.html');
      });
      
      app.listen(8080, '127.0.0.1')
      

      【讨论】:

      • app.listen启动服务器后为什么要重复app.use(express.static(__dirname + '/public'));
      • 将 html 页面作为静态服务与仅使用 express 加载非静态页面有什么区别?
      【解决方案11】:

      我经常用这个

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

      请小心,因为这会共享 /web 目录中的任何内容。

      希望对你有帮助

      【讨论】:

        【解决方案12】:

        如果你使用的是 node.js 的 express 框架

        安装 npm ejs

        然后添加配置文件

        app.set('port', process.env.PORT || 3000);
        app.set('views', __dirname + '/views');
        app.set('view engine', 'ejs');
        app.set('view engine', 'jade');
        app.use(express.favicon());
        app.use(express.logger('dev'));
        app.use(express.bodyParser());
        app.use(express.methodOverride());
        app.use(app.router)
        

        ;

        从导出模块 form.js 渲染页面 在视图目录中有 html 文件 将 ejs 文件名扩展为 form.html.ejs

        然后创建form.js

        res.render('form.html.ejs');

        【讨论】:

        • 这是什么烂摊子?
        【解决方案13】:

        1) 最好的方法是设置静态文件夹。在您的主文件中(app.js | server.js | ???):

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

        public/css/form.html
        public/css/style.css

        然后你从“公共”文件夹中获得静态文件:

        http://YOUR_DOMAIN/form.html
        http://YOUR_DOMAIN/css/style.css
        

        2)

        您可以创建文件缓存。
        使用方法 fs.readFileSync

        var cache = {};
        cache["index.html"] = fs.readFileSync( __dirname + '/public/form.html');
        
        app.get('/', function(req, res){    
            res.setHeader('Content-Type', 'text/html');
            res.send( cache["index.html"] );                                
        };);
        

        【讨论】:

        【解决方案14】:

        我试图用一个快速的 RESTful API 设置一个有角度的应用程序,并多次登陆这个页面,尽管它没有帮助。以下是我发现的有效方法:

        app.configure(function() {
            app.use(express.static(__dirname + '/public'));         // set the static files location
            app.use(express.logger('dev'));                         // log every request to the console
            app.use(express.bodyParser());                          // pull information from html in POST
            app.use(express.methodOverride());                      // simulate DELETE and PUT
            app.use(express.favicon(__dirname + '/public/img/favicon.ico'));
        });
        

        然后在你的 api 路由的回调中看起来像:res.jsonp(users);

        您的客户端框架可以处理路由。 Express 用于提供 API。

        我的回家路线如下所示:

        app.get('/*', function(req, res) {
            res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
        });
        

        【讨论】:

          【解决方案15】:

          使用 Express 4.0.0,您唯一需要做的就是在 app.js 中注释掉 2 行:

          /* app.set('views', path.join(__dirname, 'views'));
          app.set('view engine', 'jade'); */ //or whatever the templating engine is.
          

          然后将您的静态文件放到 /public 目录中。示例:/public/index.html

          【讨论】:

            【解决方案16】:

            我希望允许对“/”的请求由 Express 路由处理,而之前它们由静态中间件处理。这将允许我渲染 index.html 的常规版本或加载连接 + 缩小 JS 和 CSS 的版本,具体取决于应用程序设置。受Andrew Homeyer's answer 的启发,我决定将我的 HTML 文件(未经修改)拖到视图文件夹中,像这样配置 Express

               app.engine('html', swig.renderFile);
               app.set('view engine', 'html');
               app.set('views', __dirname + '/views');  
            

            并像这样创建了一个路由处理程序

             app.route('/')
                    .get(function(req, res){
                        if(config.useConcatendatedFiles){
                            return res.render('index-dist');
                        }
                        res.render('index');       
                    });
            

            效果很好。

            【讨论】:

              【解决方案17】:

              我在 2 行下面添加了它,它对我有用

                  app.set('view engine', 'html');
                  app.engine('html', require('ejs').renderFile);
              

              【讨论】:

              • 它给了我以下错误“错误:在 Function.Module._resolveFilename (module.js:338:15) at Function.Module._load (module.js:280 :25) 在 Module.require (module.js:364:17) 在 require (module.js:380:17) "
              • @LygubOrg 在您的工作目录中运行 npm install ejs --save
              • 是否只需要添加一个依赖来服务一个html文件?
              【解决方案18】:

              在 Express 路由中尝试 res.sendFile() 函数。

              var express = require("express");
              var app     = express();
              var path    = require("path");
              
              
              app.get('/',function(req,res){
                res.sendFile(path.join(__dirname+'/index.html'));
                //__dirname : It will resolve to your project folder.
              });
              
              app.get('/about',function(req,res){
                res.sendFile(path.join(__dirname+'/about.html'));
              });
              
              app.get('/sitemap',function(req,res){
                res.sendFile(path.join(__dirname+'/sitemap.html'));
              });
              
              app.listen(3000);
              
              console.log("Running at Port 3000");
              

              在这里阅读:http://codeforgeek.com/2015/01/render-html-file-expressjs/

              【讨论】:

                【解决方案19】:
                res.sendFile(__dirname + '/public/login.html');
                

                【讨论】:

                  【解决方案20】:

                  在 server.js 中,请包含

                  var express = require("express");
                  var app     = express();
                  var path    = require("path");
                  
                  
                  app.get('/',function(req,res){
                    res.sendFile(path.join(__dirname+'/index.html'));
                    //__dirname : It will resolve to your project folder.
                  });
                  

                  【讨论】:

                    【解决方案21】:

                    将以下行添加到您的代码中

                    1. 将 package.json 文件中的“jade”替换为“ejs”,将“X.Y.Z”(版本)替换为“*”

                        "dependencies": {
                         "ejs": "*"
                        }
                      
                    2. 然后在您的 app.js 文件中添加以下代码:

                      app.engine('html', require('ejs').renderFile);

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

                    3. 记住将所有 .HTML 文件保存在视图文件夹中

                    干杯:)

                    【讨论】:

                      【解决方案22】:

                      我不想依赖 ejs 来简单地传递 HTML 文件,所以我只是自己编写了微型渲染器:

                      const Promise = require( "bluebird" );
                      const fs      = Promise.promisifyAll( require( "fs" ) );
                      
                      app.set( "view engine", "html" );
                      app.engine( ".html", ( filename, request, done ) => {
                          fs.readFileAsync( filename, "utf-8" )
                              .then( html => done( null, html ) )
                              .catch( done );
                      } );
                      

                      【讨论】:

                        【解决方案23】:

                        要在节点中呈现 Html 页面,请尝试以下操作,

                        app.set('views', __dirname + '/views');
                        
                        app.engine('html', require('ejs').renderFile);
                        
                        • 你需要通过npm安装ejs模块,比如:

                             npm install ejs --save
                          

                        【讨论】:

                        • 这个解决方案对我有用。虽然我也尝试过静态选项。你能解释一下它背后的机制吗?谢谢!
                        【解决方案24】:

                        这是快递服务器的完整文件演示!

                        https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906

                        希望对你有所帮助!

                        // simple express server for HTML pages!
                        // ES6 style
                        
                        const express = require('express');
                        const fs = require('fs');
                        const hostname = '127.0.0.1';
                        const port = 3000;
                        const app = express();
                        
                        let cache = [];// Array is OK!
                        cache[0] = fs.readFileSync( __dirname + '/index.html');
                        cache[1] = fs.readFileSync( __dirname + '/views/testview.html');
                        
                        app.get('/', (req, res) => {
                            res.setHeader('Content-Type', 'text/html');
                            res.send( cache[0] );
                        });
                        
                        app.get('/test', (req, res) => {
                            res.setHeader('Content-Type', 'text/html');
                            res.send( cache[1] );
                        });
                        
                        app.listen(port, () => {
                            console.log(`
                                Server is running at http://${hostname}:${port}/ 
                                Server hostname ${hostname} is listening on port ${port}!
                            `);
                        });

                        【讨论】:

                          【解决方案25】:

                          文件夹结构:

                          .
                          ├── index.html
                          ├── node_modules
                          │   ├──{...}
                          └── server.js
                          

                          server.js

                          var express = require('express');
                          var app = express();
                          
                          app.use(express.static('./'));
                          
                          app.get('/', function(req, res) {
                              res.render('index.html');
                          });
                          
                          app.listen(8882, '127.0.0.1')
                          

                          index.html

                          <!DOCTYPE html>
                          <html>
                          <body>
                          
                          <div> hello world </div>
                          
                          </body>
                          </html>
                          

                          输出:

                          你好世界

                          【讨论】:

                            【解决方案26】:

                            如果您尝试提供一个 HTML 文件,其中已经包含它的所有内容,那么它不需要被“渲染”,它只需要被“提供”。渲染是指在将页面发送到浏览器之前让服务器更新或注入内容,并且它需要额外的依赖项,如 ejs,正如其他答案所示。

                            如果你只是想根据他们的请求将浏览器定向到一个文件,你应该像这样使用res.sendFile()

                            const express = require('express');
                            const app = express();
                            var port = process.env.PORT || 3000; //Whichever port you want to run on
                            app.use(express.static('./folder_with_html')); //This ensures local references to cs and js files work
                            
                            app.get('/', (req, res) => {
                              res.sendFile(__dirname + '/folder_with_html/index.html');
                            });
                            
                            app.listen(port, () => console.log("lifted app; listening on port " + port));
                            

                            这样除了 express 之外你不需要额外的依赖。如果您只想让服务器发送您已经创建的 html 文件,那么上面是一种非常轻量级的方式。

                            【讨论】:

                              【解决方案27】:

                              对于纯 html,您不需要任何 npm 包或中间件

                              就用这个吧:

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

                              【讨论】:

                                【解决方案28】:

                                index.js

                                var express = require('express');
                                var app = express();
                                app.use(express.static(__dirname + '/public'));
                                
                                
                                app.get('/', function(req, res) {
                                    res.render('index.html');
                                });
                                
                                
                                app.listen(3400, () => {
                                    console.log('Server is running at port 3400');
                                })
                                

                                将您的 index.html 文件放入公共文件夹中

                                <!DOCTYPE html>
                                <html>
                                <head>
                                    <title>Render index html file</title>
                                </head>
                                <body>
                                    <h1> I am from public/index.html </h1>
                                </body>
                                </html>
                                

                                现在在终端中运行以下代码

                                节点索引.js

                                【讨论】:

                                  【解决方案29】:

                                  很遗憾,到了 2020 年左右,express 还没有添加不使用 response 对象的 sendFile 方法来渲染 HTML 页面的方法。使用sendFile 不是问题,但以path.join(__dirname, 'relative/path/to/file') 的形式向它传递参数感觉不对。为什么用户应该将__dirname 加入文件路径?它应该默认完成。为什么服务器的根目录不能默认为项目目录?此外,安装模板依赖项只是为了呈现静态 HTML 文件也是不正确的。我不知道解决这个问题的正确方法,但如果我必须提供静态 HTML,那么我会这样做:

                                  const PORT = 8154;
                                  
                                  const express = require('express');
                                  const app = express();
                                  
                                  app.use(express.static('views'));
                                  
                                  app.listen(PORT, () => {
                                      console.log(`Server is listening at port http://localhost:${PORT}`);
                                  });
                                  

                                  上面的例子假设项目结构有一个views 目录并且静态HTML文件在里面。例如,假设views 目录有两个名为index.htmlabout.html 的HTML 文件,那么要访问它们,我们可以访问:localhost:8153/index.html 或只是localhost:8153/ 以加载index.html 页面和@ 987654334@ 加载about.html。我们可以使用类似的方法来为 react/angular 应用程序提供服务,方法是将工件存储在 views 目录中,或者仅使用默认的 dist/&lt;project-name&gt; 目录并在服务器 js 中进行如下配置:

                                  app.use(express.static('dist/<project-name>'));
                                  

                                  【讨论】:

                                    【解决方案30】:

                                    Express 4.x

                                    发送.html文件,没有模板引擎...

                                    //...
                                    // Node modules
                                    const path = require('path')
                                    //...
                                    // Set path to views directory
                                    app.set('views', path.join(__dirname, 'views'))
                                    /**
                                     * App routes
                                     */
                                    app.get('/', (req, res) => {
                                      res.sendFile('index.html', { root: app.get('views') })
                                    })
                                    //...
                                    
                                    .
                                    ├── node_modules
                                    │
                                    ├── views
                                    │   ├──index.html
                                    └── app.js
                                    

                                    【讨论】:

                                    • 我必须使用var app = express(); app.set('views', path.join(__dirname, '../views'));。如果没有“../folderName”,它会在路由文件夹中查找。
                                    猜你喜欢
                                    • 1970-01-01
                                    • 2018-12-13
                                    • 2013-03-04
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2019-04-17
                                    • 2019-11-18
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多