[英]IIS Url Rewite: Add Trailing Slash, Preserve Anchors and Query Strings
我搜索了几个 SO 帖子,但没有找到我要找的东西。 它可能存在,但可能已经相当老了,不会出现在我面前。 I found a post ( Nginx rewrite: add trailing slash, preserve anchors and query strings ) so close to what I need, but it's regex solution does not work for URL Rewrite for IIS, unless I'm doing it wrong.
问题
我正在尝试在 url 路径的末尾添加一个正斜杠/
,同时还保留任何现有的查询字符串?
和锚#
。
所需的解决方案
基本上,这是每个问题的预期结果:
Entry: https://my.site.com/about
Result: https://my.site.com/about/
Entry: https://my.site.com/about?query=string
Result: https://my.site.com/about/?query=string
Entry: https://my.site.com/about#TestAnchor
Result: https://my.site.com/about/#TestAnchor
Entry: https://my.site.com/about?query=string#TestAnchor
Result: https://my.site.com/about/?query=string#TestAnchor
当前测试
我们当前的正则表达式忽略了查询字符串和锚点,但我现在想考虑它们。
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^.?]+[^.?/])$" />
<action type="Redirect" url="{R:1}/" redirectType="Permanent" />
</rule>
我还测试了另一个正则表达式,但它仅在 url 包含查询字符串和锚点时才有效。
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^(.*)(\?.*?)(\#.*?)$" />
<action type="Redirect" url="{R:1}/{R:2}{R:3}" redirectType="Permanent" />
</rule>
注意:我刚刚测试了最后一个( ^(.*)(\?.*?)(\#.*?)$
),它实际上不起作用。 如果/
在?
测试通过了它不应该通过的,所以我在这里还有更多工作要做。
问题
是否有一个正则表达式可以用来解决这个问题,还是我需要使用多个规则?
您可以尝试使用此正则表达式https://regex101.com/r/6TSqaP/1 。 如果 url 已经有一个结尾'/'
,这匹配每个提供的示例并解决问题。
^((?:https?:\/\/[\w\.]*)(?:\w+\/)?(?:\w+)(?!\/))(\?.*?)?(\#.*?)?$
我使用您的第二个示例作为我的正则表达式的基础,具有以下逻辑。 url 的部件: scheme://authority/path?query#fragment
scheme://authority/path
部分?query
#fragment
正则表达式解释
^( # should start with this
(?:https?:\/\/[\w\.]*) # match the http or https protocol and the domain
(?:\w+\/)? # match the path except the last element of it (optional)
(?:\w+)(?!\/) # match the last path element, but only if it's not closed with '/'
) # {R:1}
(\?.*?)? # {R:2} query (optional)
(\#.*?)? # {R:3} fragment (optional)
$ # string should end
Nginx
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^((?:https?:\/\/[\w\.]*)(?:\w+\/)?(?:\w+)(?!\/))(\?.*?)?(\#.*?)?$" />
<action type="Redirect" url="{R:1}/{R:2}{R:3}" redirectType="Permanent" />
</rule>
Trailing Slash
重写 URI,同时保留Anchors
和Query
字符串<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)" />
<action type="Redirect" url="{R:1}/{R:2}" redirectType="Permanent" />
</rule>
IIS使用ECMAScript ,所以你可以在这里试试: https://regexr.com/6ef98
https://localhost --> https://localhost/
https://localhost? --> https://localhost/?
https://localhost/ --> https://localhost/
https://my.site.com --> https://my.site.com/
https://my.site.com? --> https://my.site.com/?
https://my.site.com/ --> https://my.site.com/
https://my.site.com/about.php --> https://my.site.com/about.php
https://my.site.com/about.php? --> https://my.site.com/about.php?
https://my.site.com/about --> https://my.site.com/about/
https://my.site.com/about? --> https://my.site.com/about/?
https://my.site.com/about/ --> https://my.site.com/about/
https://my.site.com/about/? --> https://my.site.com/about/?
https://my.site.com/about?query --> https://my.site.com/about/?query
https://my.site.com/about/?query --> https://my.site.com/about/?query
https://my.site.com/about.php?query --> https://my.site.com/about.php?query
https://my.site.com/about#hash --> https://my.site.com/about/#hash
https://my.site.com/about/#hash --> https://my.site.com/about/#hash
https://my.site.com/about.php#hash --> https://my.site.com/about.php#hash
https://my.site.com/about?query#hash --> https://my.site.com/about/?query#hash
https://my.site.com/about/?query#hash --> https://my.site.com/about/?query#hash
https://my.site.com/folder.name/about?query --> https://my.site.com/folder.name/about/?query
https://my.site.com/about?query#hash:http://test.com?q --> https://my.site.com/about/?query#hash:http://test.com?q
^([^?#]+?)\/?([?#].*)?$
第 1 组: ^
首先, [^?#]
除?
之外的任何字符 / #
,Go 多但懒+?
(先停止,看下一个)
忽略: \/?
那么如果/
存在与否
第 2 组: [?#]
= ?
/ #
和.*
在$
End, (...)?
如果存在
它运作良好。 但它不会正确处理:
https://my.site.com/about.php?query --> https://my.site.com/about.php/?query !!!
所以让我们添加一个例外......
Name.name.name.ext
作为Group #2怎么办?^([^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?)$
(?:...)
非捕获组([^/?#]+\.[^/?#]+)?
寻找任何可能的文件名或(?:[?#].*)?
任何可能的查询或锚字符串
现在一切正常,除了这个:
https://my.site.com? --> https://my.site.com? !!!
所以我们需要第 1 组中的另一个例外
^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)
(...|...)
Alternative [^/]+:\/\/[^/#?]+
首先检查(不是懒惰的)任何模式,例如...://...
直到不是/ #?
存在?
现在它工作得很好!
实际上我不认为我们应该在 IIS 上重写它,因为这些原因:
#
可以是文件夹名称的一部分(按%23
)我的意思是:
https://my.site.com/ --> (=Call root)
https://my.site.com/about --> (=Call root > Folder/File name about)
https://my.site.com/about/ --> (=Call root > Folder name about)
https://my.site.com/about?query --> (=Call root > Folder/File name about + Query)
https://my.site.com/about/?query --> (=Call root > Folder name about + Query)
https://my.site.com/about.php?query --> (=Call root > File name about.php + Query)
[When browser strip it:]
https://my.site.com/about#hash --> (=Call root > Folder/File name about + Anchor)
https://my.site.com/about/#hash --> (=Call root > Folder name about + Anchor)
https://my.site.com/about.php#hash --> (=Call root > File name about.php + Anchor)
[If not?]
https://my.site.com/folder#name/?query#hash
https://my.site.com/folder.name/about.php?query=one/two
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.