如何使得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
前缀,并根据需要处理服务器端。