如何解决如何mod_rewrite包含路径和参数的查询字符串?
我的网站使用了一个相当复杂的查询字符串参数:其值是包含参数的路径。
对于SEO(搜索引擎优化)等。我现在正尝试mod_rewrite缩短的版本...
-
example.com/path/c1/d1/e1.html?x=x1&y=y1
-
example.com/path/c2/d2/e2.html?x=x2&y=y2
-
example.com/path/c2/d3/e4.html?x=x5&y=y6
...到当前所需的...
-
example.com/path/?param=a/b/c1/d1/e1?x=x1&y=y1
-
example.com/path/?param=a/b/c2/d2/e2?x=x2&y=y2
-
example.com/path/?param=a/b/c2/d3/e4?x=x5&y=y6
所以目标是...
- 删除固定部分(
?param=a/b/
)以缩短地址,并 可见地址中没有两个?
- 保留查询字符串值的必要变量路径组成部分(例如
c1/d1/e1
或c2/d2/e2
或c2/d3/e4
) - 在查询字符串值的
.html
之前的最后部分添加?
,以使文件夹结构的显示深度降低1级 - 保留查询字符串值的必要变量参数(例如
?x=x1&y=y1
或?x=x2&y=y2
或?x=x5&y=y6
)
经过数小时的研究并尝试了许多无效的方法后,我在这里注册,以征求您关于如何解决此问题的建议。您愿意帮忙吗?
编辑/其他信息:
- 在固定字符串
/path/?param=a/b/
之后,它总是3个可变路径段,例如c1/d1/e1
。 - 这些可变段可以包含字母数字字符
a-z
A-Z
0-9
,破折号-
以及方括号符号(
和)
。 li>
- 对参数值(x1,y1)相同。另外,由于URL编码,y1可以包含百分比符号
%
。 - 使用两个问号(一个问号开始查询字符串,另一个问号作为参数值的一部分)看起来无效,但是可以使用。
- 处理请求的实际文件是
/path/index.php
。
解决方法
使用mod_rewrite在.htaccess
文件顶部尝试以下操作:
RewriteEngine on
# REDIRECT: /path/?param=a/b/c1/d1/e1?x=1&y=y1
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s/path/(?:index\.php)?\?param=a/b/([^/]+/[^/]+/[^/]+)\?(x=[^&]+&y=[^&]+)\s
RewriteRule ^(path)/(?:index\.php)?$ /$1/%1.html?%2 [R=302,L]
# REWRITE: /path/c1/d1/e1.html?x=x1&y=y1
RewriteCond %{QUERY_STRING} ^(x=[^&]+&y=[^&]+)$
RewriteRule ^(path)/([^/]+/[^/]+/[^/]+)\.html$ $1/index.php?param=a/b/$2?%1 [L]
第一个规则将所有对以/path/?param=a/b/c1/d1/e1?x=1&y=y1
(index.php
为可选形式)“旧” URL的 direct 请求重定向到“新”的规范网址,格式为/path/c1/d1/e1.html?x=x1&y=y1
。这对搜索引擎和任何无法更新的第三方入站链接都是有利的。但是,您必须已经将所有内部链接更改为“新”规范URL。
通过与THE_REQUEST
(而不是QUERY_STRING
)进行匹配,我们通过防止重写的URL被重定向来避免重定向循环。 THE_REQUEST
包含请求标头的第一行,并且其他重写均未更改。例如,THE_REQUEST
将包含以下形式的字符串:
GET /path/?param=a/b/c1/d1/e1?x=1&y=y1 HTTP/1.1
这是当前的302(临时)重定向。为避免潜在的缓存问题,请在测试可以正常工作后,才将其更改为301(永久)重定向。
第二条规则内部重写 对“新”规范URL的请求,例如。 /path/c1/d1/e1.html?x=x1&y=y1
,返回到原始/基础URL路径,例如/path/index.php?param=a/b/c1/d1/e1?x=1&y=y1
。如注释中所述,最后一个URL参数之前的&
是有意未转义(即URL解码)的。
$1
和$2
反向引用返回到RewriteRule
模式中捕获的组。而%1
和%2
反向引用是指前面 CondPattern 中捕获的组。
这些变量段可以包含字母数字字符
a-z
A-Z
0-9
,破折号-
和括号符号(
和)
。
我在上面的正则表达式中使用了更通用(更短)的子模式,它将匹配更多字符,但可以说更易于阅读。即。 [^/]+
-匹配除斜杠以外的所有内容,[^&]+
-匹配除&
以外的所有内容。
如果您只想只匹配允许的字符,则可以将上述子模式更改为[a-zA-Z0-9()%-]+
或[\w()%-]+
,它们也与下划线(_
)匹配。
更新:x和y只是参数名称的示例,但实际上可以有很多不同的参数名称。
参数具有多个字符。它们由字母a-z,A-Z和将来的数字0-9组成。参数x和y可能不止两个。
也许只匹配任何查询字符串(只要有一个查询字符串)即可。
请尝试以下操作:
# REDIRECT: /path/?param=a/b/c1/d1/e1?x=1&y=y1
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s/path/(?:index\.php)?\?param=a/b/([^/]+/[^/]+/[^/]+)\?([^\s]+)
RewriteRule ^(path)/(?:index\.php)?$ /$1/%1.html?%2 [R=302,L]
# REWRITE: /path/c1/d1/e1.html?x=x1&y=y1
RewriteCond %{QUERY_STRING} ^(.+)$
RewriteRule ^(path)/([^/]+/[^/]+/[^/]+)\.html$ $1/index.php?param=a/b/$2?%1
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。