![](/img/trans.png)
[英]Angular app on Kubernetes Ingress when using non-root path
[英]angular app in kubernetes using nginx ingress path
经过一番挖掘后,我决定发布这个问题,希望会出现一个正确的答案:)
目标:在 k8s 中部署 angular 应用程序,并通过具有可自定义路径和参数化路由的 nginx 入口将其公开。 应该工作的电话:
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
问题:不支持参数化路由/c/:id
。 未调用工厂,因此未设置动态APP_BASE_HREF
。 调用不正常:
http://my-url/my-app/c/my-id
在那里,没有正确检测到APP_BASE_URL
,并且 angular 尝试从http://my-url/my-app/c/runtime.js
加载资源。
提供完整的代码示例将很难且很长,但将提供一些片段
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
(图表版本: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
其中{{.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
我们拥有的路线。
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
只需使用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;
}
在 APP_INITIALIZER 完成之前调用 APP_BASE_HREF 令牌的 Providerfactory
在@aakash 建议之后,我分析了HashStrategy
。
为了支持/:id
我们可以在路由配置src/app/routing.module.ts
中使用HashStrategy 。 有了HashStrategy
,所谓的hash片段,就不会发送到服务器了。
src/app/routing.module
...
@NgModule({
imports: [ RouterModule.forRoot(routes, {useHash: true}) ],
exports: [ RouterModule ]
})
在这种情况下,请求将如下所示:
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
你想支持路径:/? 您可以将 Hash 策略与路由器模块一起使用。 这样你的额外路由不会 go 到服务器
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.