AngularJS 和 Express 路由 404
Posted
技术标签:
【中文标题】AngularJS 和 Express 路由 404【英文标题】:AngularJS and Express routing 404 【发布时间】:2015-01-11 02:27:50 【问题描述】:我有一个以下 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。这可能吗?
谢谢
【问题讨论】:
这里没人能帮我吗? 我也有同样的问题,你有没有弄清楚是什么问题:) 很遗憾没有:( 我想知道这是不是因为你需要有两个路由? IE。你需要你的角度路由只接听它自己的调用,否则你会遇到问题,例如调用 api (即假设你有 www.../api/getdata 和 www.../api/savedata 你需要一种让 Angular 知道的方法应该回答 /、/garage、任何其他组合,但不是 /api/.... 可能是错误的 我最大的问题是,否则在 Angular 例程中似乎根本不起作用,而是向服务器发出请求 【参考方案1】:不确定这是否有帮助,但这种路由工作得很好。 (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,知道在一两年前发生了一些变化,关于 angular 的拆分(所以 Route 等是一个单独的模块)。不确定是不是这样。
我有时仍然会收到 404,但我认为这是允许 Angular 获取路由的服务器端,但无法完全回答该问题如何路由(服务器/角度)协同工作或什么优先。
【讨论】:
当你在浏览器中输入 /aaaa 时,你会被重定向到 /test? 是的,如果我放任何东西(包括 /aaaa),它会很好地重定向。 这很奇怪,因为我的配置看起来非常相似,但是当请求 /aaaa 请求被发送到服务器并且浏览器下载 index.html 时。你用什么浏览器? 我使用 chrome。如果它与我遇到的问题类似,则问题可能出在您的服务器路由中。其他路线有效吗?【参考方案2】:我遇到了与您完全相同的问题,并为您提供了 2 种可能的解决方案!
//////////////////////////
解决方案 #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)中的一些文件夹具有不同的规则,您希望提供和渲染:
应用/ serve:如果您的网站执行 GET /app/controller.js,您希望向它们提供文字文件。 公开/ serve:如果您的网站确实 GET /public/img/logo.jpg,您希望向它们提供文字文件。 观看次数/ render:如果您的网站确实 GET views/home,您希望 render 他们从您的 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');
);
;
//////////////////////////
希望有帮助!
【讨论】:
以上是关于AngularJS 和 Express 路由 404的主要内容,如果未能解决你的问题,请参考以下文章
请求新页面时如何将 AngularJS 路由与 Express (Node.js) 一起使用?
使用 Express/Passport、AngularJS 和 ensureLoggedIn 的身份验证和路由在“/”url 上不起作用
如何使用 Express、AngularJS、Socket.io 广播和获取通知?