请求新页面时如何将 AngularJS 路由与 Express (Node.js) 一起使用?

Posted

技术标签:

【中文标题】请求新页面时如何将 AngularJS 路由与 Express (Node.js) 一起使用?【英文标题】:How to use AngularJS routes with Express (Node.js) when a new page is requested? 【发布时间】:2012-10-24 16:58:13 【问题描述】:

我正在使用 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);

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

如何设置我的 Express 路线以适应这种情况?我猜这将需要在 Angular 中使用 $location (尽管我更愿意避免他们使用的丑陋的 ?searches 和 #hashes),但我对如何设置 Express 路线一无所知处理这个。

谢谢。

【问题讨论】:

你能展示一下你目前的快车路线是什么样的吗? 目前,我没有,因为 Express 从静态目录提供服务。 app.use(express.static(path.join(__dirname, 'public'))); 【参考方案1】:

使用 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');
);

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

【讨论】:

这需要一些支持。感谢大写F更正expressjs.com/4x/api.html#res.sendFile【参考方案2】:

我会创建一个包罗万象的处理程序,在发送必要数据的常规路由之后运行

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');
);

app.router 是运行所有 Express 路由的中间件(例如 app.getapp.post);通常,Express 会自动将其放在中间件链的最后,但您也可以像我们在此处所做的那样将其显式添加到链中。

然后,如果 URL 不是由 app.router 处理,最后一个中间件会将 Angular HTML 视图向下发送到客户端。这将发生在 任何 未被其他中间件处理的 URL 上,因此您的 Angular 应用必须正确处理无效路由。

【讨论】:

需要注意的是,在Express 4中不推荐使用app.router,会抛出错误。 所以按照@ShawnSolomon 的建议,只需排除app.use(app.router); 行。【参考方案3】:

我想我应该澄清一下我对使用模板引擎不感兴趣,但是让 Angular 自己提取所有 HTML 部分,Node 在这里完全作为静态服务器运行(但它不会用于 JSON API。Brian Ford 在这里展示了如何使用 Jade:http://briantford.com/blog/angular-express.html

我的应用是一个单页应用,所以我为每个可能的 URL 模式创建了一个 Express 路由,并且它们每个都做同样的事情。

fs.readFile(__dirname + '/public/index.html', 'utf8', function(err, content) 
    res.send(content);
);

我假设我必须将一些请求变量传递给 Angular,但看起来 Angular 会自动处理它。

【讨论】:

有同样的初始问题:如何从节点服务器提供特定的角度视图。但我不明白解决方案。您能否详细介绍一下您如何使路线localhost/project/3 服务于正确的视图?谢谢!

以上是关于请求新页面时如何将 AngularJS 路由与 Express (Node.js) 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

angularjs 中的路由 与 bootstrap标签选项卡的冲突 解决方案

angularjs -- 页面模板清除

angularjs配置路由后无法跳转

angular路由与a链接跳转有什么不同?

angularjs 路由 异步加载js

angularjs使用路由怎么实现返回上一页,页面内容不会刷新