在 Apache Tomcat 404 深层链接问题上部署 Angular 应用程序 [英] Deploy angular application on Apache Tomcat 404 deep links issue

查看:40
本文介绍了在 Apache Tomcat 404 深层链接问题上部署 Angular 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出如何设置 Apache Tomcat 服务器来为具有深度链接的 Angular 应用程序提供服务的方法.例如:

静态服务器在收到对 mysite.com/的请求时通常会返回 index.html.但它拒绝 mysite.com/heroes/42 并返回 404 - Not Found 错误,除非它被配置为返回 index.html.

我想在 localhost/angular 上提供 angular 应用程序,我尝试了以下操作:

1) 使用以下命令构建 Angular 应用程序:

ng build --prod --base-href .

2) 将 build 文件夹的内容(默认:dist)复制到 $ApacheLocation/webapps/angular

3) 在 $ApacheLocation/conf/Catalina/localhost/rewrite.config 处添加 RewriteRules

# 如果请求现有资产或目录,请按原样转到它RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d重写规则 ^ - [L]# 如果请求的资源不存在,使用 index.html重写规则 ^\/angular\/.*$/angular/index.html

4) 在 Host 标签下方添加阀门

 <Valve className="org.apache.catalina.valves.rewrite.RewriteValve"/>

5) 启动 Tomcat 服务器并转到 localhost/angular 会给我:

未捕获的语法错误:所有 .js 包(例如 main.bundle.js)的意外标记 <

如果我不包含重写规则,tomcat 将按预期提供 localhost/angular 但会在深层链接上提供 404.

我的设置配置:

  • tomcat 版本 9.0.0.M26
  • 角度版本 4.4.2
  • @angular/cli: 1.4.2
  • 节点:8.5.0
  • npm:5.4.2
  • 操作系统:Linux x64

解决方案

我设法解决了这个问题,例如 http://localhost:8080/angular/player/detail/4,步骤如下:

1) 使用以下命令构建 Angular 应用程序:ng build --prod -bh ./-d/angular

2) 将构建的应用程序的内容复制到 $ApacheLocation/webapps/angular

3) 重写规则:

RewriteCond %{REQUEST_PATH} !-f重写规则 ^/angular/(.*)/angular?path=$1

4) 在 app.component.ts 设置导航:

constructor(private activateRoute: ActivatedRoute, private router: Router) { }ngOnInit() {const path = this.activatedRoute.snapshot.queryParams['path'];const navigateTo = '/' + 路径;如果(路径){this.router.navigate([navigateTo]);}

}

您可以在这里找到测试项目:https://github.com/avuletica/test

重写规则说明:

# %{REQUEST_PATH} 对应于用于映射的完整路径.# !非字符# '-f' (is regular file) 把TestString当成路径名,测试它是否存在,是否是一个普通文件.# ^ 匹配字符串或行的开头# .匹配除换行符以外的任何字符# * 匹配 0 个或多个前面的标记

所以基本上,如果/angular/anything 上没有文件,tomcat 会将完整路径作为查询字符串发送到 angular 应用程序,并从该查询参数 angular 处理路由.

I'm trying to figure out the way how to setup Apache Tomcat server to serve angular application with deep links. For example:

A static server routinely returns index.html when it receives a request for mysite.com/. But it rejects mysite.com/heroes/42 and returns a 404 - Not Found error unless it is configured to return index.html instead.

I want to serve angular app on localhost/angular, I have tried following:

1) Build angular application with:

ng build --prod --base-href .

2) Copy contents of build folder(default: dist) to $ApacheLocation/webapps/angular

3) Add RewriteRules at $ApacheLocation/conf/Catalina/localhost/rewrite.config

# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]  
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d  
RewriteRule ^ - [L]

# If the requested resource doesn't exist, use index.html
RewriteRule ^\/angular\/.*$ /angular/index.html

4) Adding valve just below Host tag

 <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true"> 
   <Valve className="org.apache.catalina.valves.rewrite.RewriteValve"/>

5) Starting Tomcat server and going to localhost/angular will give me:

Uncaught SyntaxError: Unexpected token < for all .js bundles (e.g main.bundle.js)

If I don't include rewrite rules, tomcat will serve localhost/angular as expected but will give 404 on deep links.

My setup configuration:

  • tomcat version 9.0.0.M26
  • angular version 4.4.2
  • @angular/cli: 1.4.2
  • node: 8.5.0
  • npm: 5.4.2
  • os: linux x64

解决方案

I managed to fix this problem e.g http://localhost:8080/angular/player/detail/4 with following steps:

1) Build angular application with: ng build --prod -bh ./ -d /angular

2) Copy contents of builded app to $ApacheLocation/webapps/angular

3) Rewrite rule:

RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/angular/(.*) /angular?path=$1

4) Setup navigation at app.component.ts:

constructor(private activatedRoute: ActivatedRoute, private router: Router) { }

ngOnInit() {
const path = this.activatedRoute.snapshot.queryParams['path'];
const navigateTo = '/' + path;

if (path) {
  this.router.navigate([navigateTo]);
}

}

You can find test project here: https://github.com/avuletica/test

Explanation of rewrite rules:

# %{REQUEST_PATH} corresponds to the full path that is used for mapping.
# ! NOT character 
# '-f' (is regular file) Treats the TestString as a pathname and tests whether or not it exists, and is a regular file.
# ^ matches the beginning of the string or line
# . matches any charceter except line breaks
# * match 0 or more of the preceding token

So basically if there is no file on /angular/anything tomcat sends full path as query string to angular application and from that query param angular handles routing.

这篇关于在 Apache Tomcat 404 深层链接问题上部署 Angular 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆