【问题标题】:Tomcat 8 URL Rewrite IssuesTomcat 8 URL 重写问题
【发布时间】:2016-04-09 18:05:38
【问题描述】:

我已经让 tomcat 8 重写工作,但似乎在 rewrite.config 中丢失了导致最后一个条件不执行的内容。 为了他人的利益,我有 RewriteValve 为我的特定应用程序而不是全局工作。下面给出了对我有用的方法。

在我的应用程序的 META-INF context.xml 文件中,我已包含以下行

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

在我的应用程序的 WEB-INF 中,我有一个 rewrite.config 文件,在合并了在另一个 tomcat 8 重写线程中看到的反馈后,该文件说明了以下内容,关于使用 {REQUEST_FILENAME} 为空的问题。我没有使用 REQUEST_FILENAME,我的配置如下所示。

RewriteCond %{REQUEST_URI} .*\.(css|js|html|png|jpg|jpeg|gif|txt|ico) [OR]
RewriteCond %{REQUEST_URI} ^\/api\/ [OR] 
RewriteRule ^(.*)$ - 

RewriteRule ^(.*)$ /index.html 

现在,如果 URI 是 js、css 等,或者 URI 以 /api/ 开头,我看到正在评估重写规则并且没有进行替换。 即以下网址似乎可以正常工作,并且没有进行任何替换。 本地主机:8080/api/abc/xyz,本地主机:8080/css/abc.min.css

但是由于某种原因,即使 URI 有一个有效的规则可以被它击中,最后一条规则也根本没有被击中。例如。像 localhost:8080/def/ghi 这样的 URL 应该被重定向到 index.html,但它似乎没有被重写。我不确定我在 rewrite.config 中缺少什么导致这种行为。 我可以搬到一个!也有条件进行重写,但只是想在我使用 Mulitple RewriteRule 组合时弄清楚我的理解。

感谢任何帮助。

【问题讨论】:

    标签: apache tomcat mod-rewrite url-rewriting


    【解决方案1】:

    我发现这个问题是因为我遇到了类似的问题。我花了几个小时寻找不需要我将特定文件类型列入白名单的解决方案。最终我反编译了org.apache.catalina.valves.rewrite.RewriteValve,找到了答案。

    我的情况类似,但我的 Angular 应用程序嵌套在一个较旧的非 Angular 应用程序中。这意味着它的 URL 类似于 http://localhost:8080/mywebapp/ng/index.html(应用程序的 base-href 因此是“/mywebapp/ng”)。

    我对使用 REQUEST_URI、REQUEST_FILENAME 或 SCRIPT_FILENAME 的规则不满意。对我有用的是 SERVLET_PATH(不知道为什么)。

    我最终找到了一个包含这两个文件的解决方案:

    /META-INF/context.xml

    <?xml version='1.0' encoding='utf-8'?>
    <Context>
        <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
    </Context>
    

    /WEB-INF/rewrite.config

    RewriteCond %{SERVLET_PATH} !-f
    RewriteRule ^/ng/(.*)$ /ng/index.html [L]
    

    结果是所有不是真实文件的东西都由 Angular 应用程序提供服务。

    注意:这适用于 Tomcat 8.0,其中一个 AoT 编译的 Angular2 (v4.0.0) 应用程序嵌套在现有的 Web 应用程序中。

    【讨论】:

    • 我完全按照你的建议做了,但我仍然从 tomcat 得到 404,你做了任何其他更改吗?
    • @PiniCheyni:这些是我当前生产设置中的设置。在您的情况下,关于 Angular 应用程序的路由处理可能有所不同?
    • @mhvelplund 谢谢!谢谢!谢谢!我不是 tomcat 专家,我团队中的某个人决定使用 tomcat 来服务他们的 Angular 应用程序(我个人更喜欢nginx,因为它很简单)。我今天花了几个小时,因为我们想启用 html5 模式(旧的 AngularJS 应用程序)。甚至 Angular 文档angular.io/guide/deployment#production-servers 似乎也是错误的。你是我发现做对的第一个。我希望 OP 能让你的答案正确!
    • 完美运行!刚刚将 /ng/ 更改为我的文件夹名称。在 Heroku 上的 Tomcat 8.5.38 上。
    • 这很有用,只是强调了 RewriteValve 文档的糟糕程度。
    【解决方案2】:

    我好像把它修好了。我发现了一些东西并与他人分享。下面的事情终于对我有用。以下是rewrite.config 中的内容。应该放在webapps//WEB-INF/目录下。

    RewriteCond %{REQUEST_URI} .*\.(css|js|html|png|jpg|jpeg|gif|txt|ttf|json|woff|ico)$ [OR]
    RewriteCond %{REQUEST_URI} ^(/api/).*$ [OR]
    RewriteRule ^(.*)$ - [L]
    
    RewriteRule ^(.*)$ /index.html 
    

    有几件事是需要的。我确保我的应用程序是默认应用程序的方法是在 server.xml 的主机配置中添加下面的 sn-p。请注意,如果您使用这种方法使您的应用程序成为默认应用程序,则应在 server.xml 的 Context 块中添加阀门,并且它可以正常工作,并且将其放入您的 application/META-INF/context.xml 不会似乎可以解决问题。它肯定会加载配置,但不会发生重写。保存在 application/META-INF/context.xml 中的 PreResources 东西似乎工作正常。

    server.xml sn-p

    <Host name="localhost"  appBase="webapps"
                unpackWARs="false" autoDeploy="false" deployOnStartup="false">
    
            <Context path="" docBase="myapp" reloadable="false">
                <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" asyncSupported="true"/>
            </Context>  
            ....
    </Host>
    

    HTH,谢谢

    【讨论】:

    • 关于您的答案的问题 - [L] 不是表示“最后一条规则”并且最后的重写被忽略还是空白使其成为单独的评估?
    • @JECarterII 我猜L 只有在应用了 RewriteRule 时才会生效(所有条件都满足)
    猜你喜欢
    • 2015-04-30
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2011-03-23
    • 1970-01-01
    相关资源
    最近更新 更多