繁体   English   中英

IIS Url 重写:添加斜杠,保留锚点和查询字符串

[英]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

  1. 第一个捕获组匹配 url 的scheme://authority/path部分
  2. 第二个捕获组可选并且匹配?query
  3. 第三个捕获组也是可选的,用于#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>
TL;DR - IIS 用Trailing Slash重写 URI,同时保留AnchorsQuery字符串
<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 - 让我们想想你的例子:
^([^?#]+?)\/?([?#].*)?$

第 1 组: ^首先, [^?#]?之外的任何字符 / # ,Go 多但懒+? (先停止,看下一个)
忽略: \/? 那么如果/存在与否
第 2 组: [?#] = ? / #.*$ End, (...)? 如果存在

它运作良好。 它不会正确处理:

https://my.site.com/about.php?query  -->  https://my.site.com/about.php/?query  !!!

所以让我们添加一个例外......

  • 级别 2 - 如果我们将可能的文件名Name.name.name.ext作为Group #2怎么办?
^([^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?)$

(?:...)非捕获组
([^/?#]+\.[^/?#]+)? 寻找任何可能的文件名或(?:[?#].*)? 任何可能的查询或锚字符串

现在一切正常,除了这个:

https://my.site.com?  -->  https://my.site.com?  !!!

所以我们需要第 1 组中的另一个例外

  • 第 3 级- 仅将域 URI 作为替代
^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)

(...|...) Alternative [^/]+:\/\/[^/#?]+首先检查(不是懒惰的)任何模式,例如...://...直到不是/ #? 存在?

现在它工作得很好!


附言

实际上我不认为我们应该在 IIS 上重写它,因为这些原因:

我的意思是:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM