AngularJS和Express路由404

时间:2014-11-13 20:05:43

标签: angularjs node.js routing

我有一个以下的AngularJS应用程序:

angular.module('app', ['ngRoute', 'app.controllers'])
.config(['$routeProvider', function($routeProvider){
    $routeProvider
        .when('/', {
            controller: 'HomeController',
            templateUrl: 'views/home.html'
        })
        .when('/garage', {
            controller: 'GarageController',
            templateUrl: 'views/vehicle.html'
        })
        .otherwise({
            redirectTo: '/'
        });
}])
.config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode(true);
}]);

Node.js是我的后端,它的唯一目的是提供REST api(尚未实现)。快速配置如下:

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

app.get('*', function(req, res) {
   res.sendFile(__dirname + '/public/index.html');
});

问题是每当我在地址栏中放入一些无效的URL时,就像http://localhost:3000/abc请求到达服务器一样。我假设它应该由AngularJS路由处理并重定向到默认' /'页。为什么没有发生? 当发生这种情况时,将再次下载所有索引和资产文件的所有应用程序。我想告诉AngularJS - 每当有人输入无效路由时,只需路由到默认路由。这应该只是替换ng-view,而不是再次下载整个index.html。这可能吗?

由于

2 个答案:

答案 0 :(得分:0)

不确定这是否有帮助,但这种路由效果很好。 (app.js)

var routes = require('./routes/index');
var users = require('./routes/users');
var api = require('./routes/api')
var partials = require('./routes/partials')

然后在另一端使用以下代码来获得正在运行的角度路径:

    var BabyPadz = angular.module('BabyPadz', ["ngResource", "ngRoute"]).
    config(['$routeProvider', '$locationProvider',
        function ($routeProvider, $locationProvider) {
            $locationProvider.html5Mode(true);
            $routeProvider
                .when('/', {
                    templateUrl: 'partials/index',
                    controller: 'IndexController'
                })
                .when('/about', {
                    templateUrl: '/partials/about',
                    controller: 'AboutController'
                })
                .when('/contactus', {
                    templateUrl: "partials/contactus",
                    controller: 'ContactController'
                })
                .when('/boompad', {
                    templateUrl: "partials/boompad",
                    controller: "BoomController"
                })

                // route for the about page

                .otherwise({redirectTo: "/test"});
        }
    ]
);

我意识到我也使用ngResource,知道有一些东西在一两年前发生了变化,有些是关于角度的分割(所以Route等等是一个单独的模块)。不确定是否是这种情况。

我有时仍会得到404,但认为这是允许Angular选择路由的服务器端,但是无法完全回答该问题路由(服务器/角度)如何协同工作或什么得到优先考虑。

答案 1 :(得分:0)

我遇到了完全相同的问题,并为您提供了两种可能的解决方案!

//////////////////////////////

解决方案#1:列出您执行/不希望"服务的目录"

//////////////////////////////

如何:

让我们说你的目录结构是这样的:

-app/
---controllers/
---directives/
---etc.
-public/
---img/
---css/
---index.html
---etc.
-views/
---home.html
---vehicle.html
---etc.
-app.js (run with 'node app.js')

这3个文件夹中的一些(app,public,views)有不同的规则,您希望提供以及您要呈现

  • 应用 /
    • 提供:如果您的网站执行了GET /app/controller.js,您希望提供文字文件。
  • 公开 /
    • 发送:如果您的网站是GET /public/img/logo.jpg,您希望发送给他们
    • 文字文件。
  • 视图 /
    • 渲染:如果您的网站有GET views / home,您希望从angular.js路径中渲染视图。

现在,从您的node / express js文件中,找到或添加以下内容:

//This tells node that these folders are for STATIC SERVING files (meaning literal files). 
//And Yes! You can use multiple to indicate multiple directories.
app.use(express.static(path.join(__dirname, 'app')));
app.use(express.static(path.join(__dirname, 'public')));

更多信息:

app.use(express.static(__dirname + '/client/views'));表示您正在从/ client / views提供文字文件,但该目录的外部没有任何内容。见angularjs index.html in views folder

扩展示例:

这将是您可能的配置:

//app.js

var express = require('express'),
  bodyParser = require('body-parser'),
  methodOverride = require('method-override'),
  errorHandler = require('error-handler'),
  morgan = require('morgan'),
  routes = require('./routes/index'), //My special routes file
  http = require('http'),
  path = require('path');

var app = module.exports = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(morgan('dev'));
app.use(bodyParser());
app.use(methodOverride());
app.use(express.static(path.join(__dirname, 'app')));
app.use(express.static(path.join(__dirname, 'public')));

// serve index and view partials
app.get('/', routes.index);

//Partials
app.get('/partials/:name', routes.partials);

// redirect all others to the index
// BUT the static files listed above still get served statically
app.get('*', routes.index);

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('index');
};

exports.partials = function (req, res) {
  var name = req.params.name;
  res.render('partials/' + name);
};

//////////////////////////////

解决方案#2:检查文件是否存在

//////////////////////////////

如何:

保留你已有的一切,但不要尝试" res.sendFile"立即检查它是否存在。例如:

exports.all = function (req, res) {
    var name = req.params[0];
    fs.exists(path+'/'+name, function(exists){
        if(exists)
        {
                //console.log("file exists");
                res.sendFile(path+'/'+name);
        }else{
                //console.log("file does not exist");
                //redirects to index
                res.render('index');
        }
    });
};

扩展示例:

这将是您可能的配置:

//app.js

var express = require('express'),
  bodyParser = require('body-parser'),
  methodOverride = require('method-override'),
  errorHandler = require('error-handler'),
  morgan = require('morgan'),
  routes = require('./routes/index'), //My special routes file
  http = require('http'),
  path = require('path');

var app = module.exports = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(morgan('dev'));
app.use(bodyParser());
app.use(methodOverride());
app.use(express.static(path.join(__dirname, '')));

// serve index and view partials
app.get('/', routes.index);

//Partials
app.get('/partials/:name', routes.partials);

// redirect all others
app.get('*', routes.all);

http.createServer(app).listen(app.get('port'), function () {
  console.log('Express server listening on port ' + app.get('port'));
});

这是您的路线档案:

var fs = require('fs');
var path = require('path');

exports.index = function(req, res){
  res.render('index');
};

exports.partials = function (req, res) {
  var name = req.params.name;
  res.render('partials/' + name);
};

exports.all = function (req, res) {
    var name = req.params[0];
    fs.exists(path+'/'+name, function(exists){
        if(exists)
        {
                //console.log("file exists");
                res.sendFile(path+'/'+name);
        }else{
                //console.log("file does not exist");
                //redirects to index
                res.render('index');
        }
    });
};

//////////////////////////////

希望有所帮助!