[英]angular app in kubernetes using nginx ingress path
After quite some digging I've decided to post the question and hopefully a proper answer will appear:)经过一番挖掘后,我决定发布这个问题,希望会出现一个正确的答案:)
Goal : to have an angular application deployed in k8s, and exposing it via the nginx ingress with a customizable path AND parametrized routes.目标:在 k8s 中部署 angular 应用程序,并通过具有可自定义路径和参数化路由的 nginx 入口将其公开。 Call that should be working:
应该工作的电话:
http://my-url/my-app/
http://my-url/my-app/a
http://my-url/my-app/b
http://my-url/my-app/c
http://my-url/my-app/c/my-id
Problem : the parametrized route /c/:id
is not supported.问题:不支持参数化路由
/c/:id
。 The factory is not called, and therefore the dynamic APP_BASE_HREF
is not set.未调用工厂,因此未设置动态
APP_BASE_HREF
。 Call that is not working fine:调用不正常:
http://my-url/my-app/c/my-id
There, the APP_BASE_URL
is not properly detected, and angular tries to load resources from http://my-url/my-app/c/runtime.js
.在那里,没有正确检测到
APP_BASE_URL
,并且 angular 尝试从http://my-url/my-app/c/runtime.js
加载资源。
There will be hard and long to provide a full code example, but some snippets will be provided for提供完整的代码示例将很难且很长,但将提供一些片段
helm uninstall -n ingress-nginx nginx-ingress; helm install --namespace ingress-nginx nginx-ingress stable/nginx-ingress
helm uninstall -n ingress-nginx nginx-ingress; helm install --namespace ingress-nginx nginx-ingress stable/nginx-ingress
(chart version: nginx-ingress-1.33.5; app version: 0.30.0) helm uninstall -n ingress-nginx nginx-ingress; helm install --namespace ingress-nginx nginx-ingress stable/nginx-ingress
(图表版本:nginx-ingress-1.33.5;应用版本:0.30.0)
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "my-app.ui.fullname" . }}
labels:
app: {{ template "my-app.name" . }}
component: "{{ .Values.ui.name }}"
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/rewrite-target: /$2
ingress.kubernetes.io/ssl-redirect: "false"
ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: "{{ .Values.root_url }}"
http:
paths:
- path: "{{ .Values.ui.ingress.path }}(/|$)(.*)"
backend:
serviceName: {{ template "my-app.ui.fullname" . }}
servicePort: 8085
where {{.Values.ui.ingress.path }}
could be anything like /my-app
其中
{{.Values.ui.ingress.path }}
可能类似于/my-app
src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
src/app/routing.module.ts
The routes we have.我们拥有的路线。
const routes: Routes = [
{ path: '',
redirectTo: '/overview',
data: { title: 'Overview'},
pathMatch: 'full' },
{ path: 'overview',
data: { title: 'Overview'},
component: AComponent },
{ path: 'b',
data: { title: 'B'},
component: BComponent },
{ path: 'c/:id',
data: { title: 'C detail'},
component: CComponent },
{ path: 'c',
data: { title: 'C detail'},
component: CComponent },
{ path: '**',
component: PageNotFoundComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes,
{enableTracing: false}
) ],
exports: [ RouterModule ]
})
export class RoutingModule { }
export const ROUTES_PATH = routes.map(p => p["path"])
src/app/app.module.ts
Just taking the APP_BASE_HREF
modifier:只需使用
APP_BASE_HREF
修饰符:
import { getBaseLocation } from './common-utils';
/**
* Modules
*/
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule,
RoutingModule
...
],
providers: [
Title,
{
provide: APP_BASE_HREF,
useFactory: getBaseLocation
}
],
bootstrap: [ AppComponent ],
entryComponents: [ t ]
})
export class AppModule { }
src/app/common-utils.ts
import { ROUTES_PATH } from './routing.module';
export function getBaseLocation() {
let paths: string[] = location.pathname.split('/');
let basePath: string = (paths && !ROUTES_PATH.includes(paths[1]) && paths[1]) || ''; // Default: ''
return '/' + basePath;
}
Providerfactory for APP_BASE_HREF token is called before APP_INITIALIZER is done 在 APP_INITIALIZER 完成之前调用 APP_BASE_HREF 令牌的 Providerfactory
https://github.com/angular/angular/issues/25932 https://github.com/angular/angular/issues/25932
Angular 2 Set APP_BASE_HREF with a value from a Promise / Observable Angular 2 使用 Promise / Observable 中的值设置 APP_BASE_HREF
After @aakash suggestion, I have analyzed the HashStrategy
.在@aakash 建议之后,我分析了
HashStrategy
。
To suuport /:id
we can use HashStrategy in the routing configuration src/app/routing.module.ts
.为了支持
/:id
我们可以在路由配置src/app/routing.module.ts
中使用HashStrategy 。 With HashStrategy
the, so called hash fragment, will not be sent to the server.有了
HashStrategy
,所谓的hash片段,就不会发送到服务器了。
src/app/routing.module
...
@NgModule({
imports: [ RouterModule.forRoot(routes, {useHash: true}) ],
exports: [ RouterModule ]
})
In that case, the requests will looked as follows:在这种情况下,请求将如下所示:
http://my-url/my-app/
http://my-url/my-app/#/a
http://my-url/my-app/#/b
http://my-url/my-app/#/c
http://my-url/my-app/#/c/my-id
You want to support path with:/?你想支持路径:/? you can use Hash Strategy with router module.
您可以将 Hash 策略与路由器模块一起使用。 That way your extra routes will not go to the server
这样你的额外路由不会 go 到服务器
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.