Javascript 如何使Angularjs路由在HTML5模式下与expressJs路由一起工作
昨天我在stackoverflow()上发布了一个问题,问我为什么在刷新网页并发现它是由HTML5模式引起的之后,css和javascript没有包含在我的网页上,所以我从昨天开始一直在寻找这个问题的解决方案,但我真的无法得到答案 我的文件夹结构 app.jsJavascript 如何使Angularjs路由在HTML5模式下与expressJs路由一起工作,javascript,node.js,angularjs,express,Javascript,Node.js,Angularjs,Express,昨天我在stackoverflow()上发布了一个问题,问我为什么在刷新网页并发现它是由HTML5模式引起的之后,css和javascript没有包含在我的网页上,所以我从昨天开始一直在寻找这个问题的解决方案,但我真的无法得到答案 我的文件夹结构 app.js var express = require('express') , routes = require('./routes') , user = require('./routes/user') , http = requi
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'));
});
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");
};
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(){
})
index.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'));
});
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");
};
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先呈现母版页,然后再呈现其他母版页,但它不起作用
angularJs
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'));
});
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");
};
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。如果路由与“/”和“/:name”(例如,路由类似于/user/1)不匹配,将呈现routes.risk
要使express首先呈现母版页,您需要删除“/”和“/:name”的路由匹配器,并保留将匹配每个路由的通用匹配器(“*”)
现在,无论您提供什么url,服务器都会发回母版页。
如果调用localhost:3000/登录,服务器将发回母版页(与调用localhost:3000时的页面相同)。
Angular将看到指定了路径(/login),并将调用相应的$routeProvider.when()函数
要处理api调用(如从db获取数据、将数据保存到db),需要为此指定路由匹配器,并将其放置在通用匹配器('*')上方:
必须指出的是,在$routeProvider.when()中不使用“/api”
剩下的是静态文件的正确处理:
请记住,每个url都由通用匹配器(“*”)处理。因此,静态文件使用错误的MIME类型进行渲染。要解决此问题,您需要使所有静态文件都可以在特定路径下访问,例如“/static”。简单更新
app.use(express.static(path.join(__dirname, 'public')));
到
您需要更新母版页中的所有路径以匹配新模式:
“/js/angular.js”现在是“/static/js/angular.js”,这要感谢@bekite提供了一个合理解决方案的基础。在他的初始解决方案的基础上,我发现以下内容对我自己来说更为简洁,并且它避免了使用
/static
前缀更新和维护所有路径。请注意,app.get('*',routes.risk)
对我不起作用(Express v3.4.4),但是使用正则表达式可以:
...
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('/[a-z]{0,100}', routes.risk);
////
// alternatively:
//
// app.get('/[a-z]{0,100}', function(req, res) {
// res.sendfile('app/index.html', {title: 'Default Title', stuff: 'More stuff to send to angular'}
// });
...
根据@bekite,角度路径通过一个通用路由(如果需要,可以提供进一步的分支),并由角度$routeProvider捕获。Express路径使用
/api
前缀捕获,并根据需要在服务器端进行处理。hey bekite可能重复,谢谢您的回复!,我已经尝试过你的解决方案,但我的angular.js似乎有一些错误,当我启动我的应用程序时,网页都挂在那里并继续加载。我可以知道是什么导致了这个问题吗?我创建了一个plunker:。这将呈现一个html页面。我用的是玉模板,你用的是ejs。因此您需要编辑视图/index.jade.抱歉,不知道从哪里开始。在我看来,您还没有更新templateUrl:'main.ejs'以匹配新路径。Angularjs在找不到模板时崩溃。我想这就是你的应用程序崩溃的原因。谢谢!!如果你在我的国家,我会给你买一瓶啤酒。我很高兴我能帮你,节省你几个小时。我花了好几天的时间来运行它。我在app.get('/*'
上也遇到了同样的问题,但是当我改为app.get('/[a-z0-9\/]{0100}'时,
它按预期工作。你明白为什么会这样吗?