繁体   English   中英

如何 mod_rewrite 包含路径和参数的查询字符串?

[英]How to mod_rewrite query string which includes path and parameters?

我的网站使用了一个相当复杂的查询字符串参数:它的值是一个包含参数的路径。

对于 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

所以目标是...

  1. 去掉固定部分( ?param=a/b/ )以缩短地址并且没有两个? 在可见地址
  2. 保留查询字符串值的必要变量路径组件(如c1/d1/e1c2/d2/e2c2/d3/e4
  3. .html添加到查询字符串值之前的最后一部分? 使文件夹结构看起来少 1 级
  4. 保留查询字符串值的必要变量参数(如?x=x1&y=y1?x=x2&y=y2?x=x5&y=y6

经过数小时的研究并尝试了许多不起作用的事情,我在这里注册以征求您关于如何解决这个烂摊子的建议。 请你帮忙好吗?

编辑/附加信息:

  • 在固定字符串/path/?param=a/b/它总是像c1/d1/e1这样的 3 个可变路径段。
  • 这些可变区段可以包含字母数字字符az AZ 0-9 ,短划线符号-和托架符号()
  • 这同样适用于参数值 (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]

第一规则重定向任何直接请求的形式的“旧” URL /path/?param=a/b/c1/d1/e1?x=1&y=y1index.php是可选的)到“新”规范形式为/path/c1/d1/e1.html?x=x1&y=y1 URL。 这是为了搜索引擎和任何无法更新的第三方入站链接的利益。 但是,您必须已经将所有内部链接更改为“新”规范 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,例如。 /path/index.php?param=a/b/c1/d1/e1?x=1&y=y1 正如评论中所讨论的,最后一个 URL 参数之前的&是有意未转义的(即 URL 解码)。

$1$2反向引用返回到RewriteRule模式中捕获的组。 %1%2反向引用指的是前面CondPattern 中捕获的组。

这些可变区段可以包含字母数字字符az AZ 0-9 ,短划线符号-和托架符号()

我在上面的正则表达式中使用了更通用(和更短)的子模式,它将匹配更多字符,但可以说更容易阅读。 IE。 [^/]+ - 匹配除斜杠以外的任何内容,而[^&]+ - 匹配除&以外的任何内容。

如果您特别想只匹配允许的字符,那么您可以将上述子模式更改为[a-zA-Z0-9()%-]+[\\w()%-]+ ,这也匹配下划线 ( _ )。


更新: x 和 y 只是参数名称的示例,但实际上可以有很多不同的参数名称。
参数有多个字符。 它们由字母 az、AZ 组成,将来可能是数字 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 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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