如果导致 404,请尝试重写为其他 URL

如果导致 404,请尝试重写为其他 URL

我有一个本地 tomcat 服务器,正在开发它以使用我的本地 IIS 实例作为代理。

我这样做是因为部署服务器是一个痛苦的过程,因为很多内容不是(我称之为)独立的。来自不同项目的内容基本上被复制到服务器的根目录。我不想处理设置它的麻烦,所以在重写模块的帮助下,我可以将大部分 URL 重写为虚拟目录。

例如,

/js/* -> /someproject/js/*
/css/* -> /someproject/css/*
/**/*.pdf -> /someotherproject/pdf/*

但是,在少数特殊情况下,这种方案不起作用,特别是当目标目录有重叠时。在部署中,一些资源被放在同一个目录中,因此没有真正的方法可以区分哪个是哪个。这些文件没有严格的模式,都是混杂在一起的。

例如,

/someproject1/file1.txt -> /file1.txt
/someproject2/book2.doc -> /book2.doc

因此,给定一个 URL /file1.txt,我不知道是否可以重写为转到someproject1someproject2。因此,我认为如果对要重写的 URL 有某种层次结构,我就可以让它工作。因此,我可能会取一个 URL /file3.txt,例如 ,重写为这些模式中第一个看起来有效的模式。

/someproject1/file3.txt     # if 404, try the next
/someproject2/file3.txt     # if 404, try the next
/someotherproject/file3.txt # if 404, try the next
/file3.txt                  # fallback

这是仅使用 URL 重写模块就能表达的东西吗?

答案1

我能够让它工作。

第一个障碍是我没有意识到并非所有条件匹配类型都可在全局范围(我编写规则的地方)中使用。只有Pattern可用。我必须将范围更改为“分布式”范围(每个站点的规则)才能访问IsFileIsDirectory匹配类型。

然后,我可以用某种层次结构写出我的规则。首先重写以匹配我想要尝试的模式,然后如果它不能解析为文件,则将其重写为下一个模式并重复。

<rule name="try in project/content" stopProcessing="false">
    <match url=".*" />
    <action type="Rewrite" url="project/content/{R:0}" />
</rule>
<rule name="verify project/content" stopProcessing="false">
    <match url="(project)/content(/.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}{R:2}" />
</rule>

在我的特定情况下,我想先尝试特定的子目录,然后如果父目录不存在则尝试它们。但理论上我可以对任何路径集执行此操作,只要我知道按什么顺序尝试它们即可。


因此,对于问题中的例子,我将设置以下规则:

<rule name="try in someproject1" stopProcessing="false">
    <match url=".*" />
    <action type="Rewrite" url="someproject1/{R:0}" />
</rule>
<rule name="try in someproject2 otherwise" stopProcessing="false">
    <match url="someproject1/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="someproject2/{R:1}" />
</rule>
<rule name="try in someotherproject otherwise" stopProcessing="false">
    <match url="someproject2/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="someotherproject/{R:1}" />
</rule>
<rule name="fallback to root otherwise" stopProcessing="false">
    <match url="someotherproject/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}" />
</rule>

相关内容