usando AngularJS html5mode com nodeJS e Express

Estou usando um servidor nodeJS com o Express para servir meu aplicativo AngularJS. Isso tudo funciona bem quando estou usando rotas padrão angularJS (hashbangs), mas agora estou tentando ativar o modo html5.

Estou ativando o html5mode assim:

$locationProvider.html5Mode(true).hashPrefix('!'); 

E é assim que meu arquivo nodeJS app.js parece:

 var path = require('path'), express = require('express'), app = express(), routes = require(path.join(__dirname, 'routes')); app.configure(function() { app.use(express.logger('dev')); app.use(express.compress()); app.use(express.methodOverride()); app.use(express.bodyParser()); app.use(app.router); app.all("/*", function(req, res, next) { res.sendfile("index.html", { root: __dirname + "/../app" }); }); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); 

No entanto, isso agora serve todas as solicitações como meu arquivo index.html e, portanto, recebo o seguinte erro de requireJS:

 Uncaught SyntaxError: Unexpected token < 

Eu tentei adicionar o seguinte ao meu nodeJS app.js para servir meus resources corretamente:

 app.use("/js", express.static(__dirname + "/../app/js")); app.use("/img", express.static(__dirname + "/../app/img")); app.use("/css", express.static(__dirname + "/../app/css")); app.use("/partials", express.static(__dirname + "/../app/partials")); 

mas ainda sem sorte.

Eu também tentei replace a instrução app.all por:

 app.use(function(req, res) { // Use res.sendfile, as it streams instead of reading the file into memory. res.sendfile(__dirname + '/../app/index.html'); }); 

mas isso também não funcionou. O que posso fazer para obter o funcionamento do angularJS html5mode com nodeJS e Express? Obrigado.

Sua correção inicial (declaração de manipuladores de middleware estático para prefixos específicos) deve funcionar muito bem, mas você precisa ter certeza de que eles são declarados antes de quaisquer outras rotas (e app.router , embora você não precise explicitamente usá-lo):

 // these need to go first: app.use("/js", express.static(__dirname + "/../app/js")); app.use("/img", express.static(__dirname + "/../app/img")); app.use("/css", express.static(__dirname + "/../app/css")); app.use("/partials", express.static(__dirname + "/../app/partials")); // any other routes: app.all("/*", ...); 

Além disso, é necessário certificar-se de que os manipuladores estáticos prefixados estejam realmente declarados corretamente (caminho correto), caso contrário, eles não conseguirão localizar nenhum arquivo solicitado e as solicitações passarão para a cadeia de middleware e, em última instância, serão manipuladas pela captura. all handler (deve ser fácil o suficiente para testar comentando o manipulador catch-all e ver se alguma requisição JS / CSS / … funciona bem).

Configure o servidor expresso 4 como:

 app.use(express.static(__dirname + '/public')); app.get('/*', function(req, res){ res.sendFile(__dirname + '/public/index.html'); }); 

e angular como:

 app.config(function($stateProvider, $urlRouterProvider, $locationProvider){ $stateProvider .state('home', { url: '/', templateUrl: 'templates/main.html' }) .state('register', { url: '/register', templateUrl: 'templates/register.html' }); $urlRouterProvider.otherwise("/"); $locationProvider.html5Mode({ enabled: true, requireBase: false }); }); 

Eu estou trabalhando em um aplicativo da web usando Angularjs e Requirejs no cliente, com Nodejs no servidor.

Aqui está um código de exemplo para mostrar como eu o configurei.

Observe que este exemplo está mostrando um URL de hash, mas você pode alterá-lo facilmente modificando a function de middleware e a configuração angular

Função Middleware

 isXHR: function (req, res, next) { if (req.xhr || req.get("angular-request") === "ajaxRequest") { next(); } else { var url = req.url; var urls = url.split("/"); var last = _.last(urls); urls = _.without(urls, last); url = urls.join("/") + "#/" + last //remove the hash if you want to make it html5mode; res.redirect(url); } } 

Configuração de rota do servidor

 //I'm using express-namespace to group my routes app.namespace("/requirements", function(){ //Shared local variable used across the application var info = { app: { title: "Requirements", module: "app/requirements" // where the angular application stored } } //this is the main url that will user request Route.get("/", function (req, res) { res.cookie("profileRegisterationSteps", 0); res.render("app/requirements/index", info); }); //this is the url angular js will request Route.get("type", filters.isXHR, function (req, res) { res.render("app/requirements/profile/type", info); }); }) 

Configuração de rota do cliente

 require(['App', 'underscore', 'ngAmd'/*angular amd*/, 'autoload'/*No Sense*/, 'appLoader' /*i used to load my scripts file for the route user requested (not all scripts files only who requested) before template laoded*/, 'appRoute'/*this is a list of routes*/], function (app, _, amd, autoload, loader, routes) { app.config(function ($routeProvider, $locationProvider, $httpProvider) { //remove a clearn URL $locationProvider.html5Mode(false); //ku dar header kan si uu server ka u ogaado Request in yahay Ajax $httpProvider.defaults.headers.common['angular-request'] = "ajaxRequest"; //Route Config var Route = $routeProvider; //get all routes objects that defined in routes module _.each(routes, function (route) { // extend the routes module objects and use its properties Route.when(route.url, _.extend(route, { //call returning function in loader module and write the promise resolve: _.extend(loader(route)) })); }); Route.otherwise({ redirectTo: "/" }); }); //start the application amd.bootstrap(app); }); 

Arquivo do Apploader

 require.config({ paths: { //pages type: "Apps/requirements/pages/type" } }); define(['App'], function(app) { return function (options) { return { loader: function ($q, $rootScope) { var defer = $q.defer(); var module = options.name// the name of the route (this name corresponds to the requirejs module name above; if (!!(module)) { if (require.defined(module)) { defer.resolve(); } else { require([module], function () { $rootScope.safeApply(function () { defer.resolve(); }) }); } } else { defer.resolve(); } return defer.promise; } } } }); 

Arquivo de rotas

 define(function(){ return { { name : "type", url : "/", templateUrl : "/requirements/type", view : 'services' } } })