13

3つのパラメータを含む可能性のあるURLがあります。

  1. ?category = computers
  2. &subcategory = laptops
  3. &product = dell-inspiron-15

このURLをわかりやすいバージョンに301リダイレクトする必要があります。

http://store.example.com/computers/laptops/dell-inspiron-15/

私はこれを持っていますが、クエリ文字列パラメータが他の順序である場合は機能させることができません:

RewriteCond %{QUERY_STRING} ^category=(\w+)&subcategory=(\w+)&product=(\w+) [NC]
RewriteRule ^index\.php$ http://store.example.com/%1/%2/%3/? [R,L]
4

3 に答える 3

18

これは、1つのパラメーターを検出し、次のステップに転送してから最終的な宛先にリダイレクトすることにより、複数のステップで実現できます。

RewriteEngine On

RewriteCond %{QUERY_STRING} ^category=([^&]+) [NC,OR]
RewriteCond %{QUERY_STRING} &category=([^&]+) [NC]
RewriteRule ^index\.php$ $0/%1

RewriteCond %{QUERY_STRING} ^subcategory=([^&]+) [NC,OR]
RewriteCond %{QUERY_STRING} &subcategory=([^&]+) [NC]
RewriteRule ^index\.php/[^/]+$ $0/%1

RewriteCond %{QUERY_STRING} ^product=([^&]+) [NC,OR]
RewriteCond %{QUERY_STRING} &product=([^&]+) [NC]
RewriteRule ^index\.php/([^/]+/[^/]+)$ http://store.example.com/$1/%1/? [R,L]

と二重の状態を回避するためにOR、次を使用できます

RewriteCond %{QUERY_STRING} (?:^|&)category=([^&]+) [NC]

@TrueBlueが提案したように。

別のアプローチは、TestString QUERY_STRINGの前にアンパサンド&を付け、常にチェックすることです。

RewriteCond &%{QUERY_STRING} &category=([^&]+) [NC]

この手法( TestStringの前に付ける)を使用して、既に見つかったパラメーターを次のパラメーターに繰り越すこともできますRewriteCond。これにより、3つのルールを1つに簡略化できます

RewriteCond &%{QUERY_STRING} &category=([^&]+) [NC]
RewriteCond %1!&%{QUERY_STRING} (.+)!.*&subcategory=([^&]+) [NC]
RewriteCond %1/%2!&%{QUERY_STRING} (.+)!.*&product=([^&]+) [NC]
RewriteRule ^index\.php$ http://store.example.com/%1/%2/? [R,L]

!、すでに見つかって並べ替えられたパラメータをから分離するためにのみ使用されますQUERY_STRING

于 2013-01-13T21:32:56.207 に答える
3

私はこの種のことに対して少し異なるアプローチを取り、mod_rewriteによって設定および読み取られるENVVARを利用します。このような名前で後方参照を参照する方が読みやすく、保守しやすいと思います。これらのENV VARは、後でリクエスト処理で再利用することもできます。全体として、ここで受け入れられている答えよりも強力で柔軟なアプローチだと思います。いずれにせよ、それは私にとってうまくいきます。以下に私の要点を完全にコピーしました。

https://gist.github.com/cweekly/5ee064ddd551e1997d4cから

# Mod_rewrite is great at manipulating HTTP requests.
# Using it to set and read temp env vars is a helpful technique.
#
# This example walks through fixing a query string:
# Extract good query params, discard unwanted ones, reorder good ones, append one new one.
#
# Before: /before?badparam=here&baz=w00t&foo=1&bar=good&mood=bad
# After: /after?foo=1&bar=good&baz=w00t&mood=happy
#
# Storing parts of the request (or anything you want to insert into it) in ENV VARs is convenient.
# Note the special RewriteRule target of "-" which means "no redirect; simply apply side effects"
# This lets you manipulate the request at will over multiple steps.
#
# In a RewriteRule, set custom temp ENV VARs via [E=NAME:value]
# Note it's also possible to set multiple env vars
# like [E=VAR_ONE:hi,E=VAR_TWO:bye]
#
# You can read these values using %{ENV:VAR_NAME}e <- little "e" is not a typo
#
# Tangent:
# Note you can also read these env vars the same way, if you set them via SetEnvIf[NoCase]
# (It won't work to use SetEnv, which runs too early for mod_rewrite to pair with it.)
#
# Regex details:
# (?:) syntax means "match but don't store group in %1 backreference"
#      so (?:^|&) is simply the ^ beginning or an & delimiter
#      (the only 2 possibilities for the start of a qs param)
# ([^&]+) means 1 or more chars that are not an & delimiter

RewriteCond %{QUERY_STRING} (?:^|&)foo=([^&]+)
RewriteRule ^/before - [E=FOO_VAL:%1]

RewriteCond %{QUERY_STRING} (?:^|&)bar=([^&]+)
RewriteRule ^/before - [E=BAR_VAL:%1]

RewriteCond %{QUERY_STRING} (?:^|&)baz=([^&]+)
RewriteRule ^/before - [E=BAZ_VAL:%1]

RewriteRule ^/before /after?foo=%{FOO_VAL}e&bar=%{BAR_VAL}e&baz=%{BAZ_VAL}e&mood=happy [R=301,L]

PSこれはあなたの質問に対するコピー/貼り付け可能な解決策ではなく、むしろこの種の問題を処理する方法を正確に示しています。この理解で武装し、あなたの例のためにそれを活用することは完全に些細なことです。:)

于 2014-10-17T21:47:09.697 に答える
1

1)すべてのパラメータがURLにあることを確認する必要がある場合:

   RewriteCond %{QUERY_STRING} (^|&)category\=computers($|&)
   RewriteCond %{QUERY_STRING} (^|&)subcategory\=laptops($|&)
   RewriteCond %{QUERY_STRING} (^|&)product\=dell\-inspiron\-15($|&)
   RewriteRule ^$ http://store.example.com/computers/laptops/dell-inspiron-15/? [R=301,L]

2)パラメータの正確なセットが必要な場合:

 RewriteCond %{QUERY_STRING} ^&*(?:category\=computers|subcategory\=laptops|product\=dell\-inspiron\-15)(?!.*&\1(?:&|$))(?:&+(category\=computers|subcategory\=laptops|product\=dell\-inspiron\-15)(?!.*&\1(?:&|$))){2}&*$
 RewriteRule ^$ http://store.example.com/computers/laptops/dell-inspiron-15/? [R=301,L] 

このルールは301リダイレクトジェネレータによって生成されます

于 2019-09-17T07:38:36.893 に答える