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

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

问题描述

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

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

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

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

ng build --prod --base-href .

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

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

# 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)在主机标签正下方添加阀门

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

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

未捕获的SyntaxError:所有.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)使用以下命令构建角度应用程序:ng build --prod -bh ./-d/angular

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

3)重写规则:

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

4)在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]);
}

}

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

重写规则的说明:

# %{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

因此,基本上,如果/angular/什么都没有文件,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深层链接问题上部署角度应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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