【问题标题】:Error: No default engine was specified and no extension was provided错误:未指定默认引擎且未提供扩展名
【发布时间】:2014-06-29 00:05:46
【问题描述】:

我正在使用 node.js 和引擎设置 http 服务器。但是,我一直遇到一些我对如何解决的信息知之甚少的问题,我希望能得到一些帮助来解决这个问题。

Error: No default engine was specified and no extension was provided. 
at new View (...\node_modules\express\lib\view.js:41:42) 
at Function.app.render (...\node_modules\express\lib\application.js:484:12) 
at ServerResponse.res.render (...\node_modules\express\lib\response.js:783:7) 
at Layer.handle (...\app.js:123:7) 
at trim_prefix (...\node_modules\express\lib\router\index.js:225:17) 
at c (...\node_modules\express\lib\router\index.js:198:9) 
at Function.proto.process_params (...\node_modules\express\lib\router\index.js:253:12) 
at next (...\node_modules\express\lib\router\index.js:189:19) 
at next (...\node_modules\express\lib\router\index.js:202:7) 
at next (...\node_modules\express\lib\router\index.js:166:38)

以下是我为启动此引擎所做的设置。

var http = require('http');  
var module = require("module")
var logger = require('morgan');
var express = require('express');
var app =  module.exports = express();
var silent = 'test' == process.env.NODE_ENV;
var httpServer = http.createServer(app);  // app middleware

app.enable('strict routing');
// app.all('*', function(req, res, next)/*** CORS support.*/
// {
//   if (!req.get('Origin')) return next();// use "*" here to accept any origin
//   res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
//   res.set('Access-Control-Allow-Methods', 'GET, POST');
//   res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
//   res.set('Access-Control-Allow-Max-Age', 3600);
//   if ('OPTIONS' == req.method) return res.send(200);
//   next();
// });
app.set('views', __dirname + '/views'); // general config
app.set('view engine', 'html');
app.get('/404', function(req, res, next){
next();// trigger a 404 since no other middleware will match /404 after this one, and we're not responding here
});
app.get('/403', function(req, res, next){// trigger a 403 error
  var err = new Error('not allowed!');
  err.status = 403;
  next(err);
});
app.get('/500', function(req, res, next){// trigger a generic (500) error
  next(new Error('keyboard cat!'));
});
app.use(express.static(__dirname + '/public')); 
//error handlers
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);  
// middleware with an arity of 4 are considered error handling middleware. When you next(err)
// it will be passed through the defined middleware in order, but ONLY those with an arity of 4, ignoring regular middleware.
function clientErrorHandler(err, req, res, next) {
  if (req.xhr) {// whatever you want here, feel free to populate properties on `err` to treat it differently in here.
  res.send(err.status || 500, { error: err.message });
  } 
  else 
  { next(err);}
};
// create an error with .status. we can then use the property in our custom error handler (Connect repects this prop as well)
function error  (status, msg) {
  var err = new Error(msg);
  err.status = status;
  return err;
};
function logErrors  (err, req, res, next) {
  console.error(err.stack);
  next(err);
};
function errorHandler (err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
};

// Error handlers
// Since this is the last non-error-handling middleware use()d, we assume 404, as nothing else responded.
// $ curl http://localhost:3000/notfound
// $ curl http://localhost:3000/notfound -H "Accept: application/json"
// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
app.use(function(req, res, next){
  res.status(404); 
  if (req.accepts('html')) {// respond with html page
    res.render('404', { url: req.url });
    return;
  } 
  if (req.accepts('json')) {// respond with json
    res.send({ error: 'Not found' });
    return;
  } 
  res.type('txt').send('Not found');// default to plain-text. send()
});

// error-handling middleware, take the same form as regular middleware, however they require an
// arity of 4, aka the signature (err, req, res, next).when connect has an error, it will invoke ONLY error-handling middleware.

// If we were to next() here any remaining non-error-handling middleware would then be executed, or if we next(err) to
// continue passing the error, only error-handling middleware would remain being executed, however here
// we simply respond with an error page.
app.use(function(err, req, res, next){
  // we may use properties of the error object here and next(err) appropriately, or if we possibly recovered from the error, simply next().
  res.status(err.status || 500);
  res.render('500', { error: err });
});

if (!module.parent) {// assigning to exports will not modify module, must use module.exports
  app.listen(3000);
  silent || console.log('Express started on port 3000');
};

【问题讨论】:

    标签: node.js http express


    【解决方案1】:

    如果你没有使用视图引擎,res.render 的东西会抛出一个错误。

    如果您只想提供 json,请将代码中的 res.render('error', { error: err }); 行替换为:

    res.json({ error: err })
    

    PS:人们通常在返回的对象中也有消息:

    res.status(err.status || 500);
    res.json({
      message: err.message,
      error: err
    });
    

    【讨论】:

      【解决方案2】:

      您缺少视图引擎,例如使用jade

      改变你的

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

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

      如果您想使用对 html 友好的语法,请改用 ejs

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

      编辑

      正如你可以从 view.js Express View Module 中看到的那样

      module.exports = View;
      
      /**
       * Initialize a new `View` with the given `name`.
       *
       * Options:
       *
       *   - `defaultEngine` the default template engine name
       *   - `engines` template engine require() cache
       *   - `root` root path for view lookup
       *
       * @param {String} name
       * @param {Object} options
       * @api private
       */
      
      function View(name, options) {
        options = options || {};
        this.name = name;
        this.root = options.root;
        var engines = options.engines;
        this.defaultEngine = options.defaultEngine;
        var ext = this.ext = extname(name);
        if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
        if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
        this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
        this.path = this.lookup(name);
      }
      

      你一定已经安装了default engine

      Expressprogram.template 搜索默认布局视图,如下所示:

      mkdir(path + '/views', function(){
            switch (program.template) {
              case 'ejs':
                write(path + '/views/index.ejs', ejsIndex);
                break;
              case 'jade':
                write(path + '/views/layout.jade', jadeLayout);
                write(path + '/views/index.jade', jadeIndex);
                break;
              case 'jshtml':
                write(path + '/views/layout.jshtml', jshtmlLayout);
                write(path + '/views/index.jshtml', jshtmlIndex);
                break;
              case 'hjs':
                write(path + '/views/index.hjs', hoganIndex);
                break;
      
            }
          });
      

      您可以在下面阅读:

      program.template = 'jade';
      if (program.ejs) program.template = 'ejs';
      if (program.jshtml) program.template = 'jshtml';
      if (program.hogan) program.template = 'hjs';
      

      默认视图引擎是jade

      【讨论】:

      • 您好,您能进一步解释一下这是如何工作的吗?我开始阅读 node.js,认为这就是我所需要的,但是当我仍然无法显示我的页面时,我查找了原因并开始查看 express 信息。现在我关注了 express 4.2 页面上的信息,并遇到了您帮助解决的上述错误。现在我得到了 ejs,但它似乎仍然不是我所需要的。你能告诉我这应该如何工作吗?
      • 我曾想过阅读时必须明确定义视图引擎,即使您要注意渲染视图。但事实并非如此。
      【解决方案3】:

      注释掉代码中的res.render 行并添加next(err);。如果你没有使用视图引擎,res.render 的东西会抛出一个错误。

      抱歉,您也必须注释掉这一行:

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

      我的解决方案会导致不使用视图引擎。您不需要视图引擎,但如果这是目标,请尝试以下操作:

      app.set('views', path.join(__dirname, 'views'));
      app.set('view engine', 'jade');
      //swap jade for ejs etc
      

      在使用视图引擎时,您也需要res.render 行。像这样的:

      // error handlers
      // development error handler
      // will print stacktrace
      if (app.get('env') === 'development') {
        app.use(function(err, req, res, next) {
          res.status(err.status || 500);
          res.render('error', {
          message: err.message,
          error: err
          });
        });
      }
      // production error handler
      // no stacktraces leaked to user
      app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        next(err);
        res.render('error', {
        message: err.message,
        error: {}
        });
      });
      

      【讨论】:

        【解决方案4】:

        如果你想渲染一个 html 文件,使用:

        response.sendfile('index.html');
        

        然后你删除:

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

        将您的*.html 放入views 目录,或将public 目录作为静态目录并将index.html 放入public 目录。

        【讨论】:

        • response.sendfile() 已弃用,请改用response.sendFile()。注意大写的“F”。
        【解决方案5】:

        而不是

        app.get('/', (req, res) => res.render('Hellooooo'))
        

        使用

        app.get('/', (req, res) => res.send('Hellooooo'))
        

        【讨论】:

          【解决方案6】:

          按照方式设置视图引擎

          app.set('views', path.join(__dirname, 'views'));
          app.set('view engine', 'jade');
          

          【讨论】:

            【解决方案7】:

            如果只需要在代码中内联发送 html 代码,我们可以在下面使用

            var app = express();
            app.get('/test.html', function (req, res) {
               res.header('Content-Type', 'text/html').send("<html>my html code</html>");
            });
            

            【讨论】:

              【解决方案8】:

              请更换

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

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

              【讨论】:

                【解决方案9】:

                上面的答案都是正确的,但是我发现一个简单的错字也会产生这个错误。例如,我有 var router = express() 而不是 var router = express.Router() 并收到此错误。所以应该是这样的:

                // App.js 
                var express = require('express');
                var app = express();
                var bodyParser = require('body-parser');
                app.use(bodyParser.urlencoded({ extended:false}));
                // assuming you put views folder in the same directory as app.js
                app.set('views', __dirname + '/views')
                app.engine('ejs', ejs.renderFile);
                app.set('view engine', 'ejs');
                // router - wherever you put it, could be in app.js
                var router = express.Router();
                router.get('/', function (req,res) {
                  res.render('/index.ejs');
                })
                

                【讨论】:

                  【解决方案10】:

                  只需在您的代码中设置视图引擎。

                  var app = express(); 
                  app.set('view engine', 'ejs');
                  

                  【讨论】:

                    【解决方案11】:

                    如果您使用 express 生成器遇到此错误,我已通过使用解决它

                    express --view=ejs myapp
                    

                    而不是

                    express --view=pug myapp
                    

                    【讨论】:

                      【解决方案12】:

                      我刚刚收到此错误消息,问题是我没有正确设置中间件。

                      我正在MEAN 堆栈中构建一个博客,并且需要对我在前端使用的 .jade 文件进行正文解析。这是我的“/middleware/index.js”文件中的代码的 sn-p,来自我的项目。

                      var express = require('express');
                      var morgan = require('morgan');
                      var session = require('express-session');
                      var cookieParser = require('cookie-parser');
                      var bodyParser = require('body-parser');
                      
                      module.exports = function (app) {
                      app.use(morgan('dev'));
                      
                      // Good for now
                      // In the future, use connect-mongo or similar
                      // for persistant sessions
                      app.use(bodyParser.json());
                      app.use(bodyParser.urlencoded({
                          extended: true
                      }));
                      app.use(cookieParser());
                      app.use(session({secret: 'building a blog', saveUninitialized: true, resave: true}));
                      

                      另外,这是我的“package.json”文件,您可能使用了不同版本的技术。 注意:因为我不确定它们之间的依赖关系,所以我将整个文件包括在这里:

                      "dependencies": {
                          "body-parser": "1.12.3",
                          "consolidate": "0.12.1",
                          "cookie-parser": "1.3.4",
                          "crypto": "0.0.3",
                          "debug": "2.1.1",
                          "express": "4.12.2",
                          "express-mongoose": "0.1.0",
                          "express-session": "1.11.1",
                          "jade": "1.9.2",
                          "method-override": "2.3.2",
                          "mongodb": "2.0.28",
                          "mongoose": "4.0.2",
                          "morgan": "1.5.1",
                          "request": "2.55.0",
                          "serve-favicon": "2.2.0",
                          "swig": "1.4.2"
                        }
                      

                      希望这对某人有所帮助!万事如意!

                      【讨论】:

                        【解决方案13】:

                        您可以使用 express-error-handler 来使用静态 html 页面进行错误处理并避免定义视图处理程序。

                        该错误可能是由 404 引起的,也可能是缺少网站图标(如果您已包含先前的控制台消息,则很明显)。 'html' 的 'view handler' 似乎在 4.x express 中无效。

                        不管是什么原因,只要修改配置的其他元素,就可以避免定义(有效的)视图处理程序。

                        解决此问题的方法是:

                        • 与其他答案一样定义有效的视图处理程序
                        • 使用 send() 代替 render 直接返回内容

                        http://expressjs.com/en/api.html#res.render

                        使用没有文件路径的渲染会自动调用视图处理程序,就像您的配置中的以下两行一样:

                        res.render('404', { url: req.url });
                        

                        和:

                        res.render('500);
                        

                        确保您安装 express-error-handler 时使用:

                        npm install --save express-error-handler
                        

                        然后在你的 app.js 中导入它

                        var ErrorHandler = require('express-error-handler');
                        

                        然后更改您的错误处理以使用:

                        // define below all other routes
                        var errorHandler = ErrorHandler({
                          static: {
                            '404': 'error.html' // put this file in your Public folder
                            '500': 'error.html' // ditto
                        });
                        
                        // any unresolved requests will 404
                        app.use(function(req,res,next) {
                          var err = new Error('Not Found');
                          err.status(404);
                          next(err);
                        }
                        
                        app.use(errorHandler);
                        

                        【讨论】:

                          【解决方案14】:

                          错误:未指定默认引擎且未提供扩展名

                          我遇到了同样的问题(因为做一个平均堆栈项目)..问题是我没有提到安装 npm 的格式,即;哈巴狗或玉,ejs 等,所以要解决这个转到 npm 并输入 express --view=pug 文件夹名称。这将在您给定的文件夹中加载必要的哈巴狗文件(index.pug、layout.pug 等)。

                          【讨论】:

                            【解决方案15】:

                            如果您使用的是 NestJS,要解决此问题,您必须更改您的 main.ts 文件。 请考虑使用以下示例:

                            喜欢NestJS - MVC中的这个演示

                            import { NestFactory } from '@nestjs/core';
                            import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
                            import { AppModule } from './app.module';
                            import { join } from 'path';
                            
                            async function bootstrap() {
                              const app = await NestFactory.create<NestFastifyApplication>(
                                AppModule,
                                new FastifyAdapter(),
                              );
                              app.useStaticAssets({
                                root: join(__dirname, '..', 'public'),
                                prefix: '/public/',
                              });
                              app.setViewEngine({
                                engine: {
                                  handlebars: require('handlebars'),
                                },
                                templates: join(__dirname, '..', 'views'),
                              });
                              await app.listen(3000);
                            }
                            
                            bootstrap();
                            

                            【讨论】:

                              猜你喜欢
                              • 2019-01-16
                              • 2013-09-02
                              • 1970-01-01
                              • 1970-01-01
                              • 2023-04-09
                              • 2021-03-21
                              • 2017-10-04
                              • 2022-12-18
                              • 1970-01-01
                              相关资源
                              最近更新 更多