node.js - engine - express-handlebars npm
Express 4, NodeJS, enrutamiento AngularJS (1)
Estoy usando Express 4 para alojar mi aplicación AngularJS en mi back-end, con Nginx como mi servidor frontend. Sin embargo, el modo html5 no parece funcionar, ya que obtendré un error Can not / GET cuando trato de ingresar al enlace de la página (por ejemplo, http://localhost/login
) a través del navegador. ¿Hay alguna configuración de enrutamiento que deba hacer para mi Express / Nginx? Aquí está mi código de configuración:
Express 4:
var express = require(''express''),
app = express(),
server = require(''http'').Server(app),
bodyParser = require(''body-parser''),
db = require(''./db''),
io = require(''./sockets'').listen(server),
apiRoutes = require(''./routes/api''),
webRoutes = require(''./routes/web'');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(''/api'', apiRoutes);
app.use(express.static(__dirname + ''/public''));
server.listen(3000, function() {
console.log(''Listening on port %d'', server.address().port);
});
AngularJS:
''use strict'';
var nodeApp = angular.module(''nodeApp'',[''ngRoute'']);
nodeApp.config(function($routeProvider, $locationProvider, $controllerProvider) {
$routeProvider.when(''/'', {
templateUrl: ''partials/home.html''
}).when(''/login'', {
templateUrl: ''partials/login.html''
});
$locationProvider.html5Mode(true);
nodeApp.controllerProvider = $controllerProvider;
});
Nginx:
# the IP(s) on which your server is running
upstream test-app {
server 127.0.0.1:3000;
}
# the nginx server instance
server {
listen 0.0.0.0:80;
server_name test-app.cloudapp.net;
access_log /var/log/nginx/test-app.log;
# pass the request to the nodejs server with correct headers
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxy true;
proxy_pass http://test-app/;
proxy_redirect off;
}
}
Supongo que está utilizando una aplicación angular de "página única", por lo que una página html que utiliza ng-view cargará todos los demás parciales.
En este caso, debe hacer algo como esto:
Express 4:
var express = require(''express''),
app = express(),
server = require(''http'').Server(app),
bodyParser = require(''body-parser''),
db = require(''./db''),
io = require(''./sockets'').listen(server),
apiRoutes = require(''./routes/api''),
webRoutes = require(''./routes/web'');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(''/api'', apiRoutes);
app.use(express.static(__dirname + ''/public''));
// Here''s the new code:
app.use(''/*'', function(req, res){
res.sendfile(__dirname + ''/public/index.html'');
});
server.listen(3000, function() {
console.log(''Listening on port %d'', server.address().port);
});
El problema al que se enfrenta es que, aunque tiene la configuración de rutas para ''/ login'' antes de que se activen las rutas, deben cargarse. Entonces el servidor intenta encontrar una coincidencia para la ruta ''/ login'' que no puede devolver el 404. En el caso de las aplicaciones angulares de una sola página, todas las rutas que use en enrutamiento deben ser capturadas por una ruta, app.get(''/*'', ...
en este caso, y luego devuelva la página principal angular.js html. Tenga en cuenta que esta es la última llamada, por lo que se evaluará en último lugar, si la coloca primero evitará que todas las reglas posteriores corriendo como expreso solo ejecuta el controlador para la primera regla que encuentra.