使 Angular 路由与 Express 路由一起工作

Posted

技术标签:

【中文标题】使 Angular 路由与 Express 路由一起工作【英文标题】:Making Angular routes work with Express routes 【发布时间】:2015-08-13 07:41:20 【问题描述】:

我在设置 Angular 路由以使用 Express 时陷入僵局。

我试图在这里 Express 4, NodeJS, AngularJS routing 这样做,但没有奏效。每次 url 更改时,静态 index.html 都会提供服务,但 Angular 不会捕获部分内容。

在我的 Express 中,我有以下代码:

var express = require("express");
var app = express();
app.use(express.static(__dirname + '/app'));
app.use("*",function(req,res)
    res.sendFile(path.join(__dirname,"app/index.html"));
);
app.listen(1337, function()
    console.log("Server is listening on port 1337");
);

在我的 Angular 应用程序中,我有以下内容:

var app = angular.module("myapp",["ngRoute","appControllers"]);

    app.config(["$routeProvider","$locationProvider",function($routeProvider,$locationProvider)
            $locationProvider.html5Mode(true);
            $routeProvider
                    .when("/list",
                        templateUrl: "/partials/users.html",
                        controller: "userListCntr"
            )
                    .when("/edit", 
                        templateUrl: "/partials/edit.html",
                        controller: "userEditCntr"
            )
                    .when("/register", 
                        templateUrl: "/partials/register.html",
                        controller: "registerCntr"
            )
                    .when("/login", 
                        templateUrl: "/partials/login.html",
                        controller: "registerCntr"
            );

    ]);

我的浏览器控制台没有任何错误。 html 检查器显示: <!-- ngView: --> 所以指令有点初始化。

以及依赖列表:

dependencies": 
    "angular": "1.3.x",
    "angular-mocks": "1.3.x",
    "jquery": "1.10.2",
    "bootstrap": "~3.1.1",
    "angular-route": "1.3.x",
    "angular-resource": "1.3.x",
    "angular-animate": "1.3.x"
  

这是我的文件结构:

--app (angular app)
   --components
   --js
   --css
   --img
   --assets
   --partials
   --index.html
--node-modules
--server.js (here express settigs are)

另外,我对所有静态资源进行了如下更改,但仍然无法正常工作:

app.use(express.static(__dirname+ "/app"));
app.use('/js', express.static(__dirname + '/app/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/app/css'));
app.use('/assets', express.static(__dirname + '/app/assets'));
app.use('/components', express.static(__dirname + '/app/components'));
app.use('/img', express.static(__dirname + '/app/img'));
app.use('/partials', express.static(__dirname + '/app/partials'));

app.all('/*', function(req, res, next) 
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('/app/index.html',  root: __dirname );
);

请帮忙,因为我找不到解决方案。谢谢!

【问题讨论】:

那么,部分页面没有渲染?你确定它们正在加载吗? 不,它们没有被加载。我的控制台中没有对部分页面的 GET 请求 expressjs.com/starter/static-files.html 可能会有所帮助 我不明白你的意思?我在 express.static() 上做错了吗? 您将模板保存在哪里(用户、编辑、注册、登录)? 【参考方案1】:

如果您不将路径传递给express.use(),则默认为/。您为* 设置的处理规则要么是多余的,要么根本不起作用。

此外,由于您使用的是 html5mode,因此您需要明确地将路由与资源分开,以便 Express 不会尝试为所有请求提供您的 index.html 文件。

从Angular UI-Router 尝试这个例子以了解尺寸:

var express = require('express');
var app = express();

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));

app.all('/*', function(req, res, next) 
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('index.html',  root: __dirname );
);

app.listen(3006); //the port you want to use

【讨论】:

谢谢,但这没有用。仍然没有 GET 请求和部分渲染。我在 /app 文件夹中有我的 Angular 应用程序,所以我改变了你的答案,比如这个 app.use(express.static(__dirname+ "/app")); app.use('/js', express.static(__dirname + '/app/js')); app.use('/dist', express.static(__dirname + '/../dist')); app.use('/css', express.static(__dirname + '/app/css')); app.use('/partials', express.static(__dirname + '/app/partials')); 你能用你的文件结构更新你的问题吗?另外,您是提供静态部分还是通过 $templateCache 提供它们? 我有静态 html 部分。感谢您的帮助,我用文件结构更新了问题 对不起,请看我的文件结构(我忘了给它添加代码标签) 我已经有一分钟没有使用 Express 了。我看到他们更改了版本 4 的 API,并且 UI-Router 的示例使用了版本 3 语法。我猜你是 4 点?【参考方案2】:

感谢大家的帮助。我通过将<base href="/" /> 插入到我的 Angular index.html 的 head 部分来解决了这个问题。它对我有用,但到目前为止它就像魔术和货物编码,因为我不明白它为什么起作用:) 在这里找到解决方案:AngularJS: how to enable $locationProvider.html5Mode with deeplinking

【讨论】:

在代码中包含<base href="/" /> before <link><script> 标签非常重要,包括文件和脚本。【参考方案3】:

我只想补充一点,添加 base href= 对我有帮助。我有我的应用程序静态服务在快递和直接浏览我的角度应用程序中的路线会导致很多

拒绝执行脚本,因为它的 mime 类型 ('text/html') 不是 启用了可执行和严格的 mime 类型检查

要抛出的错误。但是添加base href 解决了这个问题,我现在可以直接浏览到我的角度路线。

【讨论】:

【参考方案4】:

虽然@kirgol 建议的使用base href= 的解决方案效果很好,但有一个替代解决方案可能会让寻找简单路线服务的人感兴趣。在这个解决方案中,我们不会使用 ExpressJS 路由

只需使用这个

app.use(express.static(__dirname + '/app'));

而不是这个

app.all('/*', function(req, res, next) 
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('index.html',  root: __dirname );
);

这样,expressJS 将自动为该静态位置的 index.html 提供服务,并自动处理路由。它的行为就像一个简单的 http 服务器。当您使用 app.all/ app.get 处理路由时 - 您必须设置 base href 以告诉 $locationProvider 它可以匹配路由的位置

【讨论】:

【参考方案5】:

我也遇到过类似的情况,使用 express 路由角度组件,这就是我能够解决路由问题的方法:

我的 Nodejs 项目设置:

构建一个用于生产的 Angular 项目并放置在公共文件夹中。

为 express 服务器创建了一个 app.js 文件,内容如下:

var express = require('express'); var app = require('express')(); const port = 8090; app.use(express.static('public')); app.listen(port,()=>console.log("App working at port : http://localhost:"+port));

运行这个只加载了根组件,我不得不使用routerLink手动通过不同的页面。如果我尝试直接使用 URL 提供子组件,则会收到 Cannot GET/URL 错误。

修复:

我添加了express-http-proxy 包,导入为 var proxy = require('express-http-proxy'); 然后在app.use(express.static('public'));之后的以下行中添加 app.use('/*',proxy('http://localhost:'+port+'/*'));

这解决了我的问题。显然有一个更标准的修复Refer Link

【讨论】:

以上是关于使 Angular 路由与 Express 路由一起工作的主要内容,如果未能解决你的问题,请参考以下文章

防止 Angular 6 路由器覆盖 Express Server 中定义的路由

Angular 和 Express 路由

Express.js 或 Angular 用于在 MEAN 应用程序中处理路由?

同时使用 Angular routeProvider 和 Express 路由

Angular 和 Express 路由如何在 mean.js 应用程序中协同工作?

Express 4.15.5 不渲染 Angular 7 路由