Node.js 带有角度路由的Expressjs路由加载直接URL时出现问题

Node.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

我在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 ,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。我尝试交换它们,但这并不重要