如何在请求新页面时使用带有Express(Node.js)的AngularJS路由?

win*_*toy 52 node.js express angularjs

我正在使用Express,它从静态目录加载AngularJS.通常情况下,我会请求http://localhost/,其中Express为我提供了我index.html和所有正确的Angular文件等.在我的Angular应用程序中,我设置了这些路径,它们替换了以下内容ng-view:

$routeProvider.when('/', {
    templateUrl: '/partials/main.html',
    controller: MainCtrl,
});

$routeProvider.when('/project/:projectId', {
    templateUrl: '/partials/project.html',
    controller: ProjectCtrl,
});

$locationProvider.html5Mode(true);
Run Code Online (Sandbox Code Playgroud)

在我的主页面上,我有一个链接<a href="/project/{{project.id}}">,它将成功加载模板并指引我http://localhost/project/3或我指定的任何ID.问题是当我尝试将浏览器定向到http://localhost/project/3或刷新页面时,请求将转到Express/Node服务器,该服务器将返回Cannot GET /project/3.

如何设置我的Express路线以适应这种情况?我猜它需要$location在Angular中使用(虽然我更愿意避免使用丑陋的搜索和#hashes),但我对如何设置Express路由来处理这个问题一无所知.

谢谢.

Gui*_*ent 65

使用express 4,您可能希望捕获所有请求并重定向到angularjs index.html页面. app.use(app.router);已不存在,并res.sendfile已被弃用,使用res.sendFile以大写˚F.

app.post('/projects/', projectController.createProject);
app.get('/projects/:id', projectController.getProject);
app.get('*', function (req, res) {
    res.sendFile('/public/index.html');
});
Run Code Online (Sandbox Code Playgroud)

将所有API路由放在每条路径的路由之前app.get('*', function (req, res){...})

  • 这需要一些赞成.感谢首都F校正http://expressjs.com/4x/api.html#res.sendFile (4认同)

Mic*_*ley 46

我会创建一个catch-all处理程序,它发送必要数据的常规路由之后运行.

app = express();
// your normal configuration like `app.use(express.bodyParser());` here
// ...
app.use(app.router);
app.use(function(req, res) {
  // Use res.sendfile, as it streams instead of reading the file into memory.
  res.sendfile(__dirname + '/public/index.html');
});
Run Code Online (Sandbox Code Playgroud)

app.router是运行所有Express路线的中间件(如app.getapp.post); 通常,Express会自动将其置于中间件链的最末端,但您也可以将其明确添加到链中,就像我们在此处所做的那样.

然后,如果URL未被处理app.router,则最后的中间件将Angular HTML视图发送到客户端.对于未由其他中间件处理的任何 URL,都会发生这种情况,因此您的Angular应用程序必须正确处理无效路由.

  • 应该注意的是,在Express 4中不推荐使用app.router并且会抛出错误. (8认同)
  • 所以根据@ShawnSolomon的建议,只要排除`app.use(app.router);`行. (2认同)