我有一个本地 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
,我不知道是否可以重写为转到someproject1
或someproject2
。因此,我认为如果对要重写的 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
可用。我必须将范围更改为“分布式”范围(每个站点的规则)才能访问IsFile
和IsDirectory
匹配类型。
然后,我可以用某种层次结构写出我的规则。首先重写以匹配我想要尝试的模式,然后如果它不能解析为文件,则将其重写为下一个模式并重复。
<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>