Node.js 带有角度路由的Expressjs路由加载直接URL时出现问题
我在expressjs中使用angular,大多数情况下,一切都正常工作,但是我在expressjs和angular中遇到了路由冲突 app.jsNode.js 带有角度路由的Expressjs路由加载直接URL时出现问题,node.js,angularjs,express,Node.js,Angularjs,Express,我在expressjs中使用angular,大多数情况下,一切都正常工作,但是我在expressjs和angular中遇到了路由冲突 app.js app.get('/',routes.index); app.get('/about/:name', aboutRoutes.partials); app.get('/partials/:name', routes.partials); //authentication //app.get('/app', ensureAuthenticated
app.get('/',routes.index);
app.get('/about/:name', aboutRoutes.partials);
app.get('/partials/:name', routes.partials);
//authentication
//app.get('/app', ensureAuthenticated ,appRoutes.app);
app.get('/app',appRoutes.app);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/[a-z]{0,100}',routes.index)
var homeContent = require('../content-config/home.json');
exports.index = function(req, res) {
res.render('template', {
headerTitle: homeContent.headerTitle,
headerContent: homeContent.headerContent,
mainTitle: homeContent.mainTitle,
mainContent: homeContent.mainContent,
employersTagLine: homeContent.employersTagLine,
candidatesTagLine: homeContent.candidatesTagLine,
providersTagLine: homeContent.providersTagLine,
fundingTagLine: homeContent.fundingTagLine,
howItWorksTitle: homeContent.howItWorksTitle,
partials: {
head: 'partials/head',
header: 'partials/header',
footer: 'partials/footer',
maincontent: 'homepage',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
learnAboutUs: 'partials/learn-about-us',
industries: 'partials/industries-blue'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
res.render('partials/'+name,content);
};
var employersContent = require('../content-config/employers.json'),
candidatesContent = require('../content-config/candidates.json'),
providersContent = require('../content-config/providers.json'),
fundingContent = require('../content-config/funding.json');
exports.us = function(req, res) {
res.render('about/us', {
partials: {
header: 'partials/header',
footer: 'partials/footer',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
switch(name)
{
case "funding":
content ={
headerTitle: fundingContent.headerTitle,
headerContent: fundingContent.headerContent,
explanation: fundingContent.explanation,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
};
break;
case "candidates":
content = {
headerTitle: candidatesContent.headerTitle,
headerContent: candidatesContent.headerContent,
explanationTitle: candidatesContent.explanationTitle,
explanationContent: candidatesContent.explanationContent,
explanationBullets: candidatesContent.explanationBullets,
resumeTitle: candidatesContent.resumeTitle,
resumeContent: candidatesContent.resumeContent,
funnelTitle: candidatesContent.funnelTitle,
funnelContent: candidatesContent.funnelContent,
partials: {
header: 'partials/header',
industries: 'partials/industries-blue',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel-candidate',
output: 'partials/candidate-grid'
}
}
break;
case "employers":
content = {
headerTitle: employersContent.headerTitle,
headerContent: employersContent.headerContent,
explanationTitle: employersContent.explanationTitle,
explanationContent: employersContent.explanationContent,
explanationBullets: employersContent.explanationBullets,
factsTitle: employersContent.factsTitle,
facts: employersContent.facts,
funnelTitle: employersContent.funnelTitle,
funnelContent: employersContent.funnelContent,
buildVsBuyTitle: employersContent.buildVsBuyTitle,
buildVsBuyContent: employersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
case "providers":
content = {
headerTitle: providersContent.headerTitle,
headerContent: providersContent.headerContent,
explanationTitle: providersContent.explanationTitle,
explanationContent: providersContent.explanationContent,
explanationBullets: providersContent.explanationBullets,
buildVsBuyTitle: providersContent.buildVsBuyTitle,
buildVsBuyContent: providersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
}
res.render('about/'+name,content);
};
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.controllers',
'myApp.filters',
'myApp.services',
'myApp.directives'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/homepage',
controller: 'MyCtrl1'
}).
when('/about/:name', {
templateUrl: name,
controller: 'MyCtrl1'
}).
when('/funnel', {
templateUrl: 'partials/funnel',
controller: 'MyCtrl2'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
路线
app.get('/',routes.index);
app.get('/about/:name', aboutRoutes.partials);
app.get('/partials/:name', routes.partials);
//authentication
//app.get('/app', ensureAuthenticated ,appRoutes.app);
app.get('/app',appRoutes.app);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/[a-z]{0,100}',routes.index)
var homeContent = require('../content-config/home.json');
exports.index = function(req, res) {
res.render('template', {
headerTitle: homeContent.headerTitle,
headerContent: homeContent.headerContent,
mainTitle: homeContent.mainTitle,
mainContent: homeContent.mainContent,
employersTagLine: homeContent.employersTagLine,
candidatesTagLine: homeContent.candidatesTagLine,
providersTagLine: homeContent.providersTagLine,
fundingTagLine: homeContent.fundingTagLine,
howItWorksTitle: homeContent.howItWorksTitle,
partials: {
head: 'partials/head',
header: 'partials/header',
footer: 'partials/footer',
maincontent: 'homepage',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
learnAboutUs: 'partials/learn-about-us',
industries: 'partials/industries-blue'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
res.render('partials/'+name,content);
};
var employersContent = require('../content-config/employers.json'),
candidatesContent = require('../content-config/candidates.json'),
providersContent = require('../content-config/providers.json'),
fundingContent = require('../content-config/funding.json');
exports.us = function(req, res) {
res.render('about/us', {
partials: {
header: 'partials/header',
footer: 'partials/footer',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
switch(name)
{
case "funding":
content ={
headerTitle: fundingContent.headerTitle,
headerContent: fundingContent.headerContent,
explanation: fundingContent.explanation,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
};
break;
case "candidates":
content = {
headerTitle: candidatesContent.headerTitle,
headerContent: candidatesContent.headerContent,
explanationTitle: candidatesContent.explanationTitle,
explanationContent: candidatesContent.explanationContent,
explanationBullets: candidatesContent.explanationBullets,
resumeTitle: candidatesContent.resumeTitle,
resumeContent: candidatesContent.resumeContent,
funnelTitle: candidatesContent.funnelTitle,
funnelContent: candidatesContent.funnelContent,
partials: {
header: 'partials/header',
industries: 'partials/industries-blue',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel-candidate',
output: 'partials/candidate-grid'
}
}
break;
case "employers":
content = {
headerTitle: employersContent.headerTitle,
headerContent: employersContent.headerContent,
explanationTitle: employersContent.explanationTitle,
explanationContent: employersContent.explanationContent,
explanationBullets: employersContent.explanationBullets,
factsTitle: employersContent.factsTitle,
facts: employersContent.facts,
funnelTitle: employersContent.funnelTitle,
funnelContent: employersContent.funnelContent,
buildVsBuyTitle: employersContent.buildVsBuyTitle,
buildVsBuyContent: employersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
case "providers":
content = {
headerTitle: providersContent.headerTitle,
headerContent: providersContent.headerContent,
explanationTitle: providersContent.explanationTitle,
explanationContent: providersContent.explanationContent,
explanationBullets: providersContent.explanationBullets,
buildVsBuyTitle: providersContent.buildVsBuyTitle,
buildVsBuyContent: providersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
}
res.render('about/'+name,content);
};
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.controllers',
'myApp.filters',
'myApp.services',
'myApp.directives'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/homepage',
controller: 'MyCtrl1'
}).
when('/about/:name', {
templateUrl: name,
controller: 'MyCtrl1'
}).
when('/funnel', {
templateUrl: 'partials/funnel',
controller: 'MyCtrl2'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
Angular App.js
app.get('/',routes.index);
app.get('/about/:name', aboutRoutes.partials);
app.get('/partials/:name', routes.partials);
//authentication
//app.get('/app', ensureAuthenticated ,appRoutes.app);
app.get('/app',appRoutes.app);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/[a-z]{0,100}',routes.index)
var homeContent = require('../content-config/home.json');
exports.index = function(req, res) {
res.render('template', {
headerTitle: homeContent.headerTitle,
headerContent: homeContent.headerContent,
mainTitle: homeContent.mainTitle,
mainContent: homeContent.mainContent,
employersTagLine: homeContent.employersTagLine,
candidatesTagLine: homeContent.candidatesTagLine,
providersTagLine: homeContent.providersTagLine,
fundingTagLine: homeContent.fundingTagLine,
howItWorksTitle: homeContent.howItWorksTitle,
partials: {
head: 'partials/head',
header: 'partials/header',
footer: 'partials/footer',
maincontent: 'homepage',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
learnAboutUs: 'partials/learn-about-us',
industries: 'partials/industries-blue'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
res.render('partials/'+name,content);
};
var employersContent = require('../content-config/employers.json'),
candidatesContent = require('../content-config/candidates.json'),
providersContent = require('../content-config/providers.json'),
fundingContent = require('../content-config/funding.json');
exports.us = function(req, res) {
res.render('about/us', {
partials: {
header: 'partials/header',
footer: 'partials/footer',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
switch(name)
{
case "funding":
content ={
headerTitle: fundingContent.headerTitle,
headerContent: fundingContent.headerContent,
explanation: fundingContent.explanation,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
};
break;
case "candidates":
content = {
headerTitle: candidatesContent.headerTitle,
headerContent: candidatesContent.headerContent,
explanationTitle: candidatesContent.explanationTitle,
explanationContent: candidatesContent.explanationContent,
explanationBullets: candidatesContent.explanationBullets,
resumeTitle: candidatesContent.resumeTitle,
resumeContent: candidatesContent.resumeContent,
funnelTitle: candidatesContent.funnelTitle,
funnelContent: candidatesContent.funnelContent,
partials: {
header: 'partials/header',
industries: 'partials/industries-blue',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel-candidate',
output: 'partials/candidate-grid'
}
}
break;
case "employers":
content = {
headerTitle: employersContent.headerTitle,
headerContent: employersContent.headerContent,
explanationTitle: employersContent.explanationTitle,
explanationContent: employersContent.explanationContent,
explanationBullets: employersContent.explanationBullets,
factsTitle: employersContent.factsTitle,
facts: employersContent.facts,
funnelTitle: employersContent.funnelTitle,
funnelContent: employersContent.funnelContent,
buildVsBuyTitle: employersContent.buildVsBuyTitle,
buildVsBuyContent: employersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
case "providers":
content = {
headerTitle: providersContent.headerTitle,
headerContent: providersContent.headerContent,
explanationTitle: providersContent.explanationTitle,
explanationContent: providersContent.explanationContent,
explanationBullets: providersContent.explanationBullets,
buildVsBuyTitle: providersContent.buildVsBuyTitle,
buildVsBuyContent: providersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
}
res.render('about/'+name,content);
};
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.controllers',
'myApp.filters',
'myApp.services',
'myApp.directives'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/homepage',
controller: 'MyCtrl1'
}).
when('/about/:name', {
templateUrl: name,
controller: 'MyCtrl1'
}).
when('/funnel', {
templateUrl: 'partials/funnel',
controller: 'MyCtrl2'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
如果我转到/然后整个页面呈现并拉入部分主页,没有问题
如果我去/漏斗,它的工作原理是一样的
如果我进入about/randompage,它会自动呈现部分,而不会呈现页面的其他部分,但是如果我从主页单击转到about/randompage,它会像预期的那样将部分拉入页面。我能做些什么来阻止路线冲突?这里发生了两件不同的事情。首先,是浏览器向服务器发出请求与向服务器发出请求之间的区别 当您的浏览器请求“/funnel”时,它将匹配您的catchall路由,并按预期返回索引页。然后发生的是Angular(以及所有其他静态资产负载),然后Angular的客户端路由器将“/漏斗”与您的Angular路由匹配。因为路由模板是partials/funnel,所以它会向服务器请求partials/funnel并加载结果 当您直接请求/about/randompage时,它将匹配一个只返回部分内容的部分路由“about/:name”。Angular发出相同的请求“/partials/”,因为templateUrl:name的映射使其相对于路由 在这个基本意义上,你可以认为它是一个“冲突”,因为你的服务器端路由不应该与你的客户端路由匹配,因为每次浏览器出现时,你需要用初始负载(索引x.html,所有的角JS文件等)来响应。p> 通常,我在支持深度链接时所做的是将角度模板文件与模块的所有静态资源放在一起。templateUrl路径都应该静态引用它们(如templateUrl:'/js/about/templates/person.html')Express可以将它们作为静态文件使用(基本html)。服务器上唯一真正的“路由”是用于ajax/服务调用等的API端点 如果您想将它包装在一个模块中,就像您使用routes和aboutRoutes一样,那么我建议将所有内容都保存在“/templates”或“/partials”路径父级中。但是,这是一个不必要的步骤,除非您实际上是通过Jade或其他一些视图引擎呈现模板。如果它们是简单的html,只需像平常一样使用express.static就可以了 我使用的catchall与你的类似,只是我不使用正则表达式。不确定是好是坏,但阅读IMO会更清晰一些。 app.use('*',routes.index)
这样,当用于深度链接时,所有客户端路由都将通过并始终返回索引页,并允许Angular管理客户端路由。希望有帮助 我注释掉了//app.get('/about/:name',aboutRoutes.partials);现在angular根本无法识别我的路线/about/randompage,我遇到了一个快速错误无法获取/about/randompage我不知道是什么原因造成的。请尝试将快速路线从/about/:name更改为/partials/about/:name。然后在angular app.js中,将templateUrl:name更改为templateUrl:'/partials/about/'+nameok我这样做了,并使用app.get('/partials/:name',routes.partials);app.get('/partials/about/:name',aboutRoutes.partials);当('/about/:name',{templateUrl:'/partials/about/'+name,controller:'MyCtrl1'})时。我仍然在直接url引用中遇到“无法获取”错误,然后单击它时,partials/:name正在捕获它,而不是partials/about/:name。我尝试交换它们,但这并不重要