【问题标题】:Deploy angular application on Apache Tomcat 404 deep links issue在 Apache Tomcat 404 深度链接问题上部署 Angular 应用程序
【发布时间】:2017-09-19 11:36:51
【问题描述】:

我正在尝试找出如何设置 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) 将构建文件夹的内容(默认: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 会给我:

Uncaught SyntaxError: Unexpected token 适用于所有 .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

【问题讨论】:

  • 我遇到了这个问题,我知道如何解决这个问题,只需在此处留下您的 index .html 内容和您想要放置项目的路径。然后我会留下一个回答,完成后回复我
  • 这里是测试项目的完整链接:github.com/avuletica/test 尝试在 localhost/angular @valakhosravi 上托管它
  • 我想看看你的 dist 文件夹(在ng build --prod --base-href 之后构建的文件夹)。
  • 使用 ng build --prod -bh 推送更改。 -d /angular 检查构建文件夹@valakhosravi

标签: apache angular tomcat deployment angular-cli


【解决方案1】:

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

1) 使用以下命令构建 Angular 应用程序: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/anything 上没有文件,tomcat 会将完整路径作为查询字符串发送到 Angular 应用程序,并从该查询参数 Angular 处理路由。

【讨论】:

  • 应该不需要进行任何客户端更改。 Angular CLI 的开发服务器支持无需此类配置的深层链接,因此它必须只能在服务器端。
  • @Ante Vulentic Antic.. 在哪里添加重写规则。?
  • 客户端更改不是最佳解决方案恕我直言
  • 我们已经解决了同样的问题,但之后遇到了一个大问题,每次部署后没有清除缓存的好方法,因为 tomcat 会覆盖 index.html 中的 no-cache 标头跨度>
【解决方案2】:

用于解决在 apache tomcat 服务器 (8, 9) 上部署 Angular 应用程序(使用 PathLocationStrategy 路由)时的深层链接问题 -

  1. 在 server.xml 中配置 RewriteValve
  2. 在rewrite.config中写入重写规则

server.xml -

...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

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

...
      </Host>
...

rewrite.config - (注意 - /hello/ 是 Angular 应用在​​ tomcat 上的上下文路径)

RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/hello/(.*) /hello/index.html

我在我的文章中记录了这个问题 - Fixing deep linking issue – Deploying angular application on Tomcat server

注意 - 实现这一点不需要客户端设置(除了来自 CLI 的默认配置)。所有客户端路由都由 Angular Routing 模块处理。

【讨论】:

    猜你喜欢
    • 2018-10-07
    • 1970-01-01
    • 2015-04-15
    • 2015-12-25
    • 2011-04-03
    • 2019-04-12
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    相关资源
    最近更新 更多