如何使用 Apache htaccess 重新排序 URL 参数/查询字符串?

2023-12-02

我有带有多面导航(过滤)的电子商务类别。过滤可以生成数千个(有用的)URL。我想减少nr。通过始终在相同的 URL 上以相同的查询字符串参数顺序显示某些内容来显示可能的 URL。

从 SEO 的角度来看,我可以使用规范标签从逻辑上消除重复的 URL,但从性能的角度来看,使用 RewriteRules 解决它会更好。

具有相同内容但不同参数顺序的示例 URL:

  • https://example.com/category/subcategory/?filter_manuf=grohe&filter_style=design&filter_family=bauedge&filter_warranty=5y
  • https://example.com/category/subcategory/?filter_style=design&filter_manuf=grohe&filter_warranty=5y&filter_family=bauedge

这些 URL 应重定向到查询参数始终以相同顺序出现的 URL。 eg:

https://example.com/category/subcategory/?filter_manuf=grohe&filter_family=bauedge&filter_style=design&filter_warranty=5y

注意:

  • 我有超过 10 个过滤条件(查询参数)
  • 参数的顺序根据用户的滤波器选择顺序而变化。它们可以按任何给定的顺序出现。
  • 仅使用的参数出现在 URL 中。有些页面的 URL 中包含一两个参数,有些页面的参数多达十个或更多。

您知道如何实现吗?

我在这个问题中发现了一些有希望的东西,但我无法让它发挥作用:
RewriteCond 以任意顺序匹配查询字符串参数


但从性能的角度来看,用RewriteRules来解决会好得多。

From a 表现从角度来看,最好在您的应用程序中解决这个问题,而不是.htaccess/mod_rewrite(即。RewriteRules)。您希望始终正确链接到规范 URL。

您当然不希望在用户应用过滤器以“更正”URL 参数顺序时从外部重定向用户。您的应用程序首先应“正确”应用 URL 参数。

“重定向”用户唯一有益的情况是,如果他们点击了第三方非规范链接(来自其他网站或搜索引擎),并且您需要解决潜在的 SEO 问题。但即便如此,如果将其作为应用程序逻辑的一部分来实现,那么纠正 URL 参数顺序的代码应该会简单得多(并且更容易维护),而不是.htaccess。执行此操作的代码在.htaccess相对更“复杂”(阅读:混乱,可能更难维护,更容易出错,等等)

然而,这是一个有趣的问题,有时最好(或有必要)将其编码为.htaccess(或 Apache 服务器配置)当您无法在应用程序中轻松执行此操作时。

使用 mod_rewrite 的解决方案.htaccess(或服务器配置)

(However, note the comments above - this may not be what you should be doing.)

这是一个相当通用的解决方案,适用于.htaccess(或服务器配置)。就目前情况而言,它适用于anyURL 路径。使其在单个 URL 路径上工作(例如/category/subcategory/,如问题中所述)然后修改pattern在决赛中RewriteRule指示。例如:

RewriteRule ^category/subcategory/$ %{REQUEST_URI}?%{ENV:NEW_QUERY_STRING} [NE,R=302,L]

或者,如果您需要将其应用于一组 URL 而不是其他 URL,则可以在顶部编写一个例外来跳过某些 URL 的这些规则。这可能是更优化的,因为它避免了对查询字符串的任何不必要的处理。

该代码块需要靠近您的顶部.htaccess文件。 (顺序很重要。)

此代码还有一个额外的“好处”,即它还通过删除任何未定义的 URL 参数(在脚本顶部)来“清理”查询字符串。

由于“简单地”确定原始 URL 参数是否已按正确顺序排列并非易事,因此脚本会使用按正确顺序排列的 URL 参数构建新的查询字符串,然后将其与原始查询进行比较字符串以确定是否需要重定向。

标准:

  • 最多 10 个 URL 参数
  • 任意数量的 URL 参数可以以任意顺序出现
  • 不应包含空 URL 参数
  • URL 参数区分大小写
  • 适用于任何 URL 路径
  • URL 参数名称与正则表达式匹配[\w-]+ (ie. a-z, A-Z, 0-9, _ and -)
  • URL 参数值不能包含@(除非 URL 已编码)
  • @@@不能出现在查询字符串中的任何位置

您只需在脚本顶部按照您希望的顺序定义 URL 参数名称即可。这些保存在环境变量中VAR_NAME_01, VAR_NAME_02等等。脚本的其余部分应保持不变,除非:

  • 您需要添加更多 URL 参数
  • 或者,更改内部使用的字符来分隔模式匹配中的部分(当前为“@").
  • 或者,将代码限制为特定的 URL 路径。

Script:

# Define the "name" of each URL parameter
# The numeric order determines the order of the resulting URL parameter list.
# Comment out any URL parameters that are not required.
SetEnvIf ^ ^ VAR_NAME_01=one
SetEnvIf ^ ^ VAR_NAME_02=two
SetEnvIf ^ ^ VAR_NAME_03=three
SetEnvIf ^ ^ VAR_NAME_04=four
SetEnvIf ^ ^ VAR_NAME_05=five
SetEnvIf ^ ^ VAR_NAME_06=six
SetEnvIf ^ ^ VAR_NAME_07=seven
SetEnvIf ^ ^ VAR_NAME_08=eight
SetEnvIf ^ ^ VAR_NAME_09=nine
SetEnvIf ^ ^ VAR_NAME_10=ten

###############################################################################
# Shouldn't need to modify directives below here...

RewriteEngine on
Options +FollowSymLinks

# -----------------------------------------------------------------------------
# Read each URL parameter (if any) and store in corresponding env var

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_01} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_01:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_02} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_02:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_03} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_03:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_04} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_04:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_05} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_05:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_06} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_06:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_07} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_07:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_08} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_08:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_09} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_09:%2]

RewriteCond %{QUERY_STRING}@%{ENV:VAR_NAME_10} (?:^|&)([\w-]+)=([^&@]+).*@\1
RewriteRule ^ - [E=VAR_VALUE_10:%2]

# -----------------------------------------------------------------------------
# Construct new query string
# Only with URL parameters that are not empty

RewriteCond %{ENV:VAR_VALUE_01} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:VAR_NAME_01}=%{ENV:VAR_VALUE_01}]

RewriteCond %{ENV:VAR_VALUE_02} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_02}=%{ENV:VAR_VALUE_02}]

RewriteCond %{ENV:VAR_VALUE_03} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_03}=%{ENV:VAR_VALUE_03}]

RewriteCond %{ENV:VAR_VALUE_04} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_04}=%{ENV:VAR_VALUE_04}]

RewriteCond %{ENV:VAR_VALUE_05} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_05}=%{ENV:VAR_VALUE_05}]

RewriteCond %{ENV:VAR_VALUE_06} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_06}=%{ENV:VAR_VALUE_06}]

RewriteCond %{ENV:VAR_VALUE_07} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_07}=%{ENV:VAR_VALUE_07}]

RewriteCond %{ENV:VAR_VALUE_08} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_08}=%{ENV:VAR_VALUE_08}]

RewriteCond %{ENV:VAR_VALUE_09} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_09}=%{ENV:VAR_VALUE_09}]

RewriteCond %{ENV:VAR_VALUE_10} .
RewriteRule ^ - [E=NEW_QUERY_STRING:%{ENV:NEW_QUERY_STRING}&%{ENV:VAR_NAME_10}=%{ENV:VAR_VALUE_10}]

# -----------------------------------------------------------------------------
# Trim "&" prefix from the NEW_QUERY_STRING
RewriteCond %{ENV:NEW_QUERY_STRING} ^&(.+)
RewriteRule ^ - [E=NEW_QUERY_STRING:%1]

# Compare with existing QUERY_STRING to determine whether it's in the correct order already
# If different then redirect...
RewriteCond %{QUERY_STRING}@@@%{ENV:NEW_QUERY_STRING} !^(.+)@@@\1
RewriteRule ^ %{REQUEST_URI}?%{ENV:NEW_QUERY_STRING} [NE,R=302,L]

如果您对此脚本的特定部分有任何疑问,请在评论中说...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Apache htaccess 重新排序 URL 参数/查询字符串? 的相关文章

  • OAuth2:查询字符串与片段

    刚刚注意到 在 OAuth2 中 当请求的授权类型为 code 时 回调将其包含在查询字符串参数中 在 之后 但是 当授权是 令牌 时 它会作为片段传递 在 之后 这看起来是规范的一部分 https datatracker ietf org
  • htaccess 仅当 HTTP 引荐来源网址不等于某些内容时才重定向

    我有以下规则将中国用户重定向到该网站的中文版本 RewriteCond HTTP Accept Language zh NC RewriteCond HTTP HOST www example com NC RewriteRule http
  • 如何通过 .htaccess 删除 URL 中任何位置的空参数或参数?

    我的意思是空参数可以在 URL 中的任何位置 每次不同的位置 每次使用不同的名称 每次在不同的 php 页面上 例如 http www example com AnyPHPpageHere php parameter1 7 paramete
  • 每个虚拟主机的错误日志?

    在一台运行 Apache 和 PHP 5 的 Linux 服务器上 我们有多个带有单独日志文件的虚拟主机 我们似乎无法分离 phperror log虚拟主机之间 覆盖此设置
  • htaccess 301 重定向 - 删除查询字符串 (QSA)

    我一直在努力处理一些 htaccess 重定向 我只是花了一些时间在堆栈上阅读和搜索 但无法获得适合我的场景的答案 我正在将旧客户端网站的 301 重定向到新客户端 旧页面有参数查询 我想从网址中删除它 menu php idCategor
  • 提交简单 PHP 表单时出现禁止错误

    我有一个不复杂的问题 这似乎比应有的更复杂 我有一个简单的表单 用于向网站添加内容 有些字段需要输入html 然而 当您在表单的不同部分输入某些 html 元素时 它会认为它讨厌您并抛出禁止的 403 错误 这是下面的表格
  • Apache mod_rewrite 将子域重写到子文件夹(通过内部重定向)

    我正在尝试编写一组 mod rewrite 规则 允许我的用户利用单个文件夹在不同项目上进行开发 而不必为每个项目添加虚拟主机 我的想法是为每个需要此功能的用户 仅 3 4 个 设置一个 全局虚拟主机 该虚拟主机类似于 my domain
  • 如何将路径添加到 Apache PATH 变量?

    我在 apache2 的 custom conf 文件中设置了以下内容 SetEnv PATH PATH opt local lib mysql5 bin this is a test 但是它不起作用 当我打电话时 hey shell ex
  • 文件缓存:查询字符串与上次修改时间?

    我正在研究缓存网站资源的方法 并注意到大多数与我类似的网站都使用查询字符串来覆盖缓存 例如 css style css v 124942823 后来 我注意到每当我保存 style css 文件时 最后修改的标头都会 更新 使得查询字符串变
  • Google App Store 警告 - 您应该尽快升级到 Apache Cordova 3.5.1 或更高版本

    我收到了一封来自 Google Play 商店的关于我的 Android 应用程序的电子邮件 这是一个通知 表明您的 com mydomain myapp 是基于 包含安全漏洞的 Apache Cordova 版本 这 包括高严重性跨应用程
  • 在 Apache 上设置虚拟主机(XAMPP、Windows 10)

    我尝试使用 XAMPP 为某些本地站点设置虚拟主机 我执行了后续步骤 在 C xampp apache conf extra httpd vhosts conf 中我添加了
  • 使用 htaccess 重写规则重定向后 CSS 未加载

    我有以下用户个人资料网址的简写 RewriteRule w profile php name of user 1 当我这样做时 该网站使用适当的 css 文件进行样式设置site com name of user 但当我这样做的时候却不是s
  • 使用 mod_wsgi 在 Apache2 上部署 Django - Django 项目的位置正确吗?

    我正在尝试在我的网络服务器上部署我的第一个 Django 项目 我对服务器配置和 Django 都很陌生 所以我很难找到我的错误 在我在网上看到的大多数教程中 生产服务器上的 Django 项目是在 var www myproject 中创
  • .htaccess 重写规则冲突

    我正在编写代码并构建一个 htaccess 文件 其中包含以下内容 RewriteEngine on RewriteRule A Za z0 9 A Za z0 9 index php id 1 NC L Handle page reque
  • 一个好的多线程 python 网络服务器?

    我正在寻找一个多线程而不是多进程的 python Web 服务器 如 apache 的 mod python 的情况 我希望它是多线程的 因为我希望有一个内存对象缓存供各种 http 线程使用 我的网络服务器做了很多昂贵的事情并计算了一些大
  • 将 WordPress 的登录/注册页面重定向到自定义登录/注册页面

    我有一个网站 有一个用户系统 我想将 WordPress 的用户系统集成到该网站的用户系统中 但我仍然想使用该网站的注册 登录页面 我不希望任何人能够使用 Wordpress 的登录或注册表单登录或注册 相反 当他们尝试访问 Wordpre
  • PHP 编译器 openssl 错误

    在提问之前 我必须说我已经tried堆栈和其他地方的每个类似问题都失败了 我无法使用composer因为这个错误 requires ext openssl gt the requested PHP extension openssl is
  • mod_rewrite 规则不起作用

    我的 htaccess 中有以下规则 RewriteRule list php categoryShortForm 1 locationShortForm world QSA RewriteRule list php categorySho
  • router.navigate 更改 URL,但不渲染组件

    而不是使用 a href my path my param a 在我的模板中 我愿意使用带参数的函数将我重定向到页面 所以 这就是我在 ts 文件中构建函数的方式 redirectToChat my param this router na
  • 在 XSSF 工作簿上设置密码保护

    我想为使用 poi 3 14 创建的 xlsx 文件添加密码保护 该文档声称 这是可能的 http poi apache org cryption html http poi apache org encryption html 使用我尝试

随机推荐