如何使用Apache htaccess对URL参数/查询字符串进行重新排序? [英] How to reorder URL parameters / query string using Apache htaccess?

查看:57
本文介绍了如何使用Apache htaccess对URL参数/查询字符串进行重新排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have eCommerce categories with faceted navigation (filtering). Filtering can generate thousands of (useful) URLs. I would like to reduce nr. of possible URLs by showing certain content always on the same URL with the same query string parameter order.

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

From an SEO point of view I could use the canonical tag to logically eliminate duplicated URLs, but from a performance point of view it would be much better to solve it with RewriteRules.

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

Example URLs with the same content but different param order:

  • 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.例如:

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

请注意:

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

您是否知道如何实现?

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

I have found something promising in this question, but I can't make it work:
RewriteCond to match query string parameters in any order

推荐答案

但是从性能的角度来看,最好使用RewriteRules解决它.

but from performance point of view it would be much better to solve it with RewriteRules.

性能的角度来看,最好在应用程序中解决此问题,而不是 .htaccess /mod_rewrite(即 RewriteRule s).您希望始终正确链接到规范URL.

From a performance point of view, it would be far better to resolve this in your application, not .htaccess/mod_rewrite (ie. RewriteRules). You want to always be correctly linking to the canonical URL.

您当然不希望外部重定向用户,因为他们应用了过滤器以纠正"用户的身份.URL参数顺序.URL参数应被应用在正确的" URL中.首先从您的应用程序开始.

You certainly don't want to be externally redirecting the user as they apply filters in order to "correct" the URL parameter order. The URL parameters should be applied in the "correct" to begin with by your application.

唯一一次重定向"将是有益的.如果用户是通过第三方非规范链接(来自其他网站或搜索引擎)访问的,则您需要解决潜在的SEO问题.但是即使这样,如果将其作为应用程序逻辑的一部分而不是 .htaccess 的一部分实施,则用于更正URL参数顺序的代码也应该更加简单(并且易于维护).在 .htaccess 中执行此操作的代码相对来说更复杂".(阅读:混乱,可能难以维护,更容易出错等)

The only time it would be beneficial to "redirect" the user is if they have followed a third party non-canonical link (from another website or search engine) and you need to resolve potential SEO issues. But even then, the code to correct the URL parameter order should be far simpler (and easier to maintain) if implemented as part of your application logic, not .htaccess. The code to do this in .htaccess is comparatively more "complex" (read: messy, potentially harder to maintain, more prone to error, etc.)

但是,这是一个有趣的问题,有时您可能无法(最好)在 .htaccess (或Apache服务器配置)中对此进行编码在您的应用程序中很容易.

However, it is an interesting problem and there might be an occasion when it is preferable (or necessary) to code this in .htaccess (or Apache server config) when you are not able to do this easily in your application.

(但是,请注意上面的注释-这可能不是您应该做的.)

这是一个合理的通用解决方案,可在 .htaccess (或服务器配置)中使用.就目前而言,它适用于 any URL路径.要使其在单个URL路径(例如,如问题所述的/category/subcategory/)上工作,然后在最终的 RewriteRule中修改 pattern 指令.例如:

This is a reasonably generic solution that works in .htaccess (or server config). As it stands, it works on any URL-path. To make it work on a single URL-path (eg. /category/subcategory/, as stated in the question) then modify the pattern in the final RewriteRule directive. For example:

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

或者,如果需要将其应用于一组URL而不是其他URL,则可以在顶部写一个例外来跳过这些规则.这样做可能会更好,因为它可以避免对查询字符串进行不必要的处理.

Or, you could write an exception at the top to skip these rules for certain URLs if you need to apply it to a group of URLs and not others. This might be more optimal as it avoids any unnecessary processing of the query string.

此代码段将需要放在您的 .htaccess 文件顶部附近.(订单很重要.)

This block of code would need to go near the top of your .htaccess file. (Order matters.)

此代码在代码中添加了好处".它也消毒"了通过删除所有未定义的URL参数(在脚本顶部)来查询字符串.

This code has the added "benefit" that it also "sanitizes" the query string by removing any URL parameters that are not defined (at the top of the script).

由于简单"地进行操作并非易事.确定原始URL参数是否已经按照正确的顺序进行操作,脚本将通过使用正确的URL参数构造新查询字符串的过程,然后将其与原始查询字符串进行比较,以确定重定向是否正确.

Since it's non-trivial to "simply" determine whether the original URL parameters are already in the correct order, the script goes through the process of constructing a new query string with the URL parameters in the correct order and then compares this to the original query string in order to determine whether a redirect is necessary.

条件:

  • 最多10个URL参数
  • 任意数量的URL参数可以按任意顺序显示
  • 不应包含空URL参数
  • URL参数区分大小写
  • 适用于任何URL路径
  • URL参数名称与正则表达式 [\ w-] + (即 az AZ 0-9 _ -)
  • URL参数值不能包含 @ (除非URL已编码)
  • @@@ 不能出现在查询字符串的任何地方
  • Up to 10 URL parameters
  • Any number of URL parameters can appear in any order
  • Empty URL parameters should not be included
  • URL parameters are case-sensitive
  • Works for any URL-path
  • URL parameter names match the regex [\w-]+ (ie. a-z, A-Z, 0-9, _ and -)
  • URL parameter values cannot contain @ (unless URL encoded)
  • @@@ cannot appear anywhere in the query string

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

You simply need to define the URL parameter names at the top of the script, in the order you wish them to be. These are held in environment variables VAR_NAME_01, VAR_NAME_02, etc. The remainder of the script should work unaltered unless:

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

脚本:

# 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]

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

If you have any queries regarding specific parts of this script just say in comments...

这篇关于如何使用Apache htaccess对URL参数/查询字符串进行重新排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆