gpt4 book ai didi

regex - IIS Url 重写 : Add Trailing Slash, 保留 anchor 和查询字符串

转载 作者:行者123 更新时间:2023-12-05 03:31:19 25 4
gpt4 key购买 nike

我已经搜索了几个 SO 帖子,但没有找到我要找的东西。它可能存在,但可能已经足够老了,不会出现在我面前。我找到了一个帖子 ( Nginx rewrite: add trailing slash, preserve anchors and query strings ) 非常接近我的需要,但它的正则表达式解决方案不适用于 IIS 的 URL 重写,除非我做错了。

问题

我正在尝试将正斜杠 / 添加到我的 url 路径的末尾,同时还保留任何现有的查询字符串 ? 和 anchor #.

所需的解决方案

基本上,这是每个问题的预期结果:

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

当前测试

我们当前的正则表达式忽略了查询字符串和 anchor ,但我现在想考虑它们。

<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^.?]+[^.?/])$" />
<action type="Redirect" url="{R:1}/" redirectType="Permanent" />
</rule>

我还测试了另一个正则表达式,但它仅在 url 同时包含查询字符串和 anchor 时才有效。

<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^(.*)(\?.*?)(\#.*?)$" />
<action type="Redirect" url="{R:1}/{R:2}{R:3}" redirectType="Permanent" />
</rule>

注意: 我刚刚测试了最后一个 (^(.*)(\?.*?)(\#.*?)$) 它实际上不起作用。如果 url 在 ? 之前已经包含 /,则测试通过,但它不应该通过,所以我在这里还有更多工作要做。

问题

我可以使用一个正则表达式来解决这个问题,还是我需要使用多个规则?

最佳答案

长话短说

IIS 使用尾部斜杠 重写(所有)URI 并保留 FragmentQuery Strings
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)" />
<action type="Redirect" url="{R:1}/{R:2}" redirectType="Permanent" />
</rule>

IIS use ECMAScript所以你可以在这里尝试: https://regexr.com/6ele7


更新

IIS 使用尾部斜杠 重写(考虑)URI 并保留 FragmentQuery Strings
<rule name="AddTrailingSlash" stopProcessing="true">
<match url="^([^/]+:\/\/[^/#?]+|[^?#]+\/[^/.?#]+)([?#].*)?$" />
<action type="Redirect" url="{R:1}/{R:2}" redirectType="Permanent" />
</rule>

在此处尝试: https://regexr.com/6fk3g


http://127.0.0.1  -->  http://127.0.0.1/
https://localhost --> https://localhost/
https://localhost? --> https://localhost/?
https://localhost/ --> https://localhost/
https://my.site.com --> https://my.site.com/
https://my.site.com:443? --> https://my.site.com:443/?
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 much but lazy +? (先停下来,看下一个)
忽略: \/? 那么如果/是否存在
第 2 组: [?#] = ?/#.*旁边的任何字符直到 $ 结束,(...)? 如果存在

效果很好。 但是它不适合处理:

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

所以让我们添加一个异常(exception)......

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

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

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

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

所以我们需要在组 #1

中另一个异常(exception)
  • 级别 3 - 仅将域 URI 作为替代方案
^([^/]+:\/\/[^/#?]+|[^?#]+?)\/?((?:[^/?#]+\.[^/?#]+)?(?:[?#].*)?$)

(...|...) 备选方案[^/]+:\/\/[^/#?]+ 首先检查(不是懒惰)是否有像 ...://... 这样的模式直到 /# ? 不存在?

现在效果很好!


+ 说明(考虑)

  • Level 4 - 如果我们只是在第一组中添加一个 Not-Accepting . & / 字符集以匹配考虑的 URI 和忽略别人?
^([^/]+:\/\/[^/#?]+|[^?#]+\/[^/.?#]+)([?#].*)?$

\/[^/.?#]+ 检查最后一个/之后的字符集是否不是/.?#

现在它更小更快了!


分析其他方法

作为@károly-szabó回答得好here ,而不是寻找不接受的字符集,我们可以寻找匹配的模式。
因此,如果我们想使用该方法但以更简单的方式(2 组)(+ 一些小的优化),正则表达式将是:

^(https?:\/\/[\w.:-]+\/?(?:[\w.-]+\/)*[\w-]+(?!\/))([?#].*)?$

但是 URI path Accepted characters更多。

因此,该 Regex 的更广泛版本可以是:

^(https?:\/\/[\w.:-]+\/?(?:[\w!#-)+-.;=@~]+\/)*[\w!#-);=@~+,-]+(?!\/))([?#].*)?$

在这里试试:https://regexr.com/6elea

注意:仍然是“multibyte Unicode 作为允许的域名”,但我在此方法中忽略了这一点。


附言

实际上我认为我们不应该在 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

关于regex - IIS Url 重写 : Add Trailing Slash, 保留 anchor 和查询字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70670470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com