如何使得Angularjs在html5mode上与expressJs路由工作

我已经发布了一个问题( CSS和JavaScript没有包括在刷新上 )昨天问我关于为什么CSS和JavaScript没有包括在我的网页上后,我刷新网页,发现它造成的html5mode,所以自昨天以来,我一直在寻找这个问题的解决scheme,但我不能真正得到答案。

我的文件夹结构

在这里输入图像描述

app.js

var express = require('express') , routes = require('./routes') , user = require('./routes/user') , http = require('http') , path = require('path') , mongoose = require('mongoose'); var app = module.exports=express(); // all environments app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/public/views'); app.set('view engine', 'ejs'); app.use(express.cookieParser()); app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.static(path.join(__dirname, 'public'))); app.use(app.router); app.use(function(request, response) { console.log("catch all"); writeFile("/public/views/master.ejs", request, response); }); // development only if ('development' == app.get('env')) { app.use(express.errorHandler()); } app.use(function (req,res) { res.status(404).render('error', { url: req.originalUrl }); }); app.get('/', routes.index); app.get('/:name', routes.view); app.get('*', routes.risk); http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); }); 

index.js

 exports.index = function(req, res){ res.render('master', { title: 'Hello World' }); }; exports.view = function (req, res) { var name = req.params.name; res.render(name); }; exports.risk = function(req, res){ res.sendfile(__dirname + "/public/views/master.ejs"); }; 

为exports.risk我试图使expressJs渲染主页面之前呈现其他,但它不工作。

angularJs

 var SymSal = angular.module('SymSal',[]). config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { $routeProvider. when('/', { templateUrl: 'main.ejs', controller: 'IndexCtrl' }). when('/login',{ templateUrl: 'login.ejs', controller: 'IndexCtrl' }). when('/register',{ templateUrl: 'register.ejs', controller: 'IndexCtrl' }). when('/about',{ templateUrl: 'about.ejs', controller: 'IndexCtrl' }). otherwise({ templateUrl: 'error.ejs' }); $locationProvider.html5Mode(true); }]); SymSal.controller('IndexCtrl',function(){ }) 

感谢您的帮助,谢谢!

为exports.risk我试图使expressJs渲染主页面之前呈现其他,但它不工作。

路线按顺序匹配:

 app.get('/', routes.index); app.get('/:name', routes.view); app.get('*', routes.risk); 

如果路由匹配'/'呈现routes.index。 如果路由不匹配“/”,检查它是否匹配“/:name”(例如/ login,/ register)并呈现routes.view。 如果路由不匹配“/”和“/:名称”(例如路由是/ user / 1)routes.risk将呈现。

要首先快速渲染母版页,您需要删除“/”和“/:name”的路由匹配器,并保留匹配每个路由的通用匹配器(“*”)。

现在,无论您提供什么url,服务器都会发回主页面。 如果您调用localhost:3000 / login,则服务器将发回主页面(如果您要调用localhost:3000,则返回相同页面)。 Angular会看到指定了一个path(/ login),并会调用相应的$ routeProvider.when()函数。

要处理api调用(比如从数据库获取数据,将数据保存到数据库),您需要为此指定一个路由匹配器,并将其放在通用匹配器('*')的上方:

 app.get('/api', routes.api); 

请注意,在$ routeProvider.when()中不要使用“/ api”。

剩下的是静态文件的正确处理:记住每个URL都由通用匹配器('*')处理。 所以静态文件得到渲染与错误的MIMEtypes。 为了解决这个问题,你需要使所有的静态文件在特定的path下可用,例如'/ static'。 只需更新

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

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

您需要更新母版页中的所有path以匹配新的模式:'/js/angular.js'现在是'/static/js/angular.js'

感谢@bekite为合理解决scheme的基础。 在他最初的解决scheme的基础上,我发现了以下一点清洁剂,避免了需要使用/static前缀更新和维护所有path。 请注意, app.get('*', routes.risk)不适用于我(Express v3.4.4),但使用正则expression式:

 ... app.use(app.router); app.use(express.static(path.join(__dirname, 'app'))); // Express routes - ensure these are not defined in Angular's app.js $routeProvider: app.get('/api', routes.api); /** * ANGULAR APP ROUTING * -------------------- * These routes will fallback to Angular for resolution of any uri: * Note that the * wildcard will not work, hence the alternate regex * It is crucial that 'static' assets never be referenced with a leading * forward slash '/', else they'll match this rule and 404's will occur */ //app.get('*', routes.risk); app.get('/[az]{0,100}', routes.risk); //// // alternatively: // // app.get('/[az]{0,100}', function(req, res) { // res.sendfile('app/index.html', {title: 'Default Title', stuff: 'More stuff to send to angular'} // }); ... 

根据@bekite,Angularpath被传递到一个通用路由(如果需要,可以提供进一步的分支),并由Angular $ routeProvider捕获。 Expresspath被捕获到/api前缀,并根据需要处理服务器端。