Erro: nenhum mecanismo padrão foi especificado e nenhuma extensão foi fornecida


132

Estou trabalhando na configuração de um servidor http usando node.js e engine. No entanto, continuo enfrentando problemas que tenho poucas informações sobre como resolver. Gostaria de receber ajuda para resolver isso, por favor.

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)

Abaixo está o que eu configurei para iniciar este mecanismo.

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');
};

Respostas:


120

O material res.render gerará um erro se você não estiver usando um mecanismo de exibição.

Se você deseja apenas servir o json, substitua as res.render('error', { error: err });linhas no seu código por:

res.json({ error: err })

PS: As pessoas também costumam ter uma mensagem no objeto retornado:

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

102

Está faltando o mecanismo de exibição, por exemplo, use jade :

mude seu

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

com

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

Se você quiser usar uma sintaxe amigável para html, use o ejs

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

EDITAR

Como você pode ler no 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);
}

Você deve ter instalado um default engine

Expresspesquise a visualização de layout padrão program.templateconforme você pode ler abaixo:

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;

      }
    });

e como você pode ler abaixo:

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

o mecanismo de visualização padrão é jade


2
Olá, você pode explicar melhor como isso funciona? Comecei a ler no node.js, pensando que era tudo o que precisava, mas quando ainda não conseguia exibir minhas páginas, procurei o motivo e passei a informações sobre o express. Agora, segui as informações na página expressa 4.2 e encontrei o erro acima do qual você ajudou. Agora eu tenho ejs e ainda não parece ser tudo o que preciso. Você pode me dar um fluxo de como isso deve funcionar, por favor?
Kobojunkie


Eu pensei que ao ler isso, você deve definir explicitamente um mecanismo de exibição, mesmo que você esteja exibindo notas. esse não é o caso.
Stevejpurves

15

Comente as res.renderlinhas do seu código e adicione-as next(err);. Se você não estiver usando um mecanismo de exibição, ores.render material gerará um erro.

Desculpe, você também precisará comentar esta linha:

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

Minha solução resultaria em não usar um mecanismo de exibição. Você não precisa de um mecanismo de visualização, mas se esse for o objetivo, tente o seguinte:

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

Você precisará das res.renderlinhas ao usar um mecanismo de exibição também. Algo assim:

// 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: {}
  });
});

12

Se você deseja renderizar um arquivo html, use:

response.sendfile('index.html');

Então você remove:

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

Coloque seu *.htmlno viewsdiretório ou ative um publicdiretório como dir estático e coloque-o index.htmlno publicdir.


4
response.sendfile()está obsoleto, use em response.sendFile()vez disso. Observe que o capital "F".
Pramesh Bajracharya

6

definir o mecanismo de visualização da seguinte maneira

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

4

Se tudo o que for necessário é enviar o código html embutido no código, podemos usar abaixo

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

0

Acabei de receber esta mensagem de erro e o problema era que eu não estava configurando meu middleware corretamente.

Estou criando um blog na pilha MEAN e precisava de análise corporal para os arquivos .jade que eu estava usando no front end. Aqui está o trecho de código do meu arquivo " /middleware/index.js ", do meu projeto.

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}));

Além disso, aqui está o meu arquivo " package.json ", você pode estar usando versões diferentes de tecnologias. Nota: como não tenho certeza das dependências entre eles, estou incluindo o arquivo inteiro aqui:

"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"
  }

Espero que isso ajude alguém! Muito bem sucedida!


0

As respostas acima estão corretas, mas descobri que um simples erro de digitação também pode gerar esse erro. Por exemplo, eu tive var router = express () em vez de var router = express.Router () e obtive esse erro. Portanto, deve ser o seguinte:

// 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');
})

0

Você pode usar express-error-handler para usar páginas html estáticas para manipulação de erros e evitar definir um manipulador de exibição.

O erro provavelmente foi causado por um 404, talvez um favicon ausente (aparente se você tivesse incluído a mensagem anterior do console). O 'view manipulador' de 'html' não parece ser válido no 4.x express.

Independentemente da causa, você pode evitar a definição de um manipulador de exibição (válido), desde que modifique elementos adicionais da sua configuração.

Suas opções para corrigir esse problema são:

  • Defina um manipulador de exibição válido como em outras respostas
  • Use send () em vez de renderizar para retornar o conteúdo diretamente

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

O uso da renderização sem um caminho de arquivo chama automaticamente um manipulador de exibição, como nas duas linhas a seguir da sua configuração:

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

e:

res.render('500);

Certifique-se de instalar o express-error-handler com:

npm install --save express-error-handler

Em seguida, importe-o no seu app.js

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

Altere o tratamento de erros para usar:

// 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);

0

Basta definir o mecanismo de exibição no seu código.

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

0

Erro: nenhum mecanismo padrão foi especificado e nenhuma extensão foi fornecida

Eu tenho o mesmo problema (para fazer um projeto de pilha médio) .. o problema é que eu não mencionei o formato para instalar o npm, ou seja; pug ou jade, ejs etc. para resolver esse goto npm e digite express --view = pug foldername. Isso carregará os arquivos pug necessários (index.pug, layout.pug etc.) na sua pasta.


0

se você tiver esse erro usando o gerador expresso, eu o resolvi usando

express --view=ejs myapp

ao invés de

express --view=pug myapp
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.