0

私は次の.htaccessルールを持っています。そして、このブロックにいくつかのルールを追加する必要があります。古いものをなくしたくない。

<FilesMatch "\.(htaccess|htpasswd|ini|phps|fla|psd|log|sh)$">
Order allow,Deny
Deny from all
</FilesMatch>

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

私のルールは次のようなものです。

- if HTTP_USER_AGENT includes BotOne
- or HTTP_USER_AGENT includes OtherBot
- or HTTP_COOKIE user_id != 1

    - if REQUEST_URI is "/" main directory
    - or REQUEST_FILENAME includes "utm_source"
    - or REQUEST_FILENAME includes "utm_medium"
    - or REQUEST_FILENAME includes "utm_campaign" and "utm_content"

        - if REQUEST_FILENAME doesn't include "/blog/"
        - or REQUEST_FILENAME doesn't include "gif"
        - or REQUEST_FILENAME doesn't include "jpg"

            - then RewriteRule all files to index.html

これを試してみました。しかし、助けにはならなかった。これらのルールをどのように書くことができますか?

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]

    RewriteCond %{HTTP_USER_AGENT} "BotOne|OtherBot" [NC,OR]
    RewriteCond %{HTTP_COOKIE} !^.*user_id=1   [NC]
    #
    RewriteCond %{REQUEST_URI} \/  [NC,OR]
    RewriteCond %{REQUEST_FILENAME} ^utm_source.*  [NC,OR]
    RewriteCond %{REQUEST_FILENAME} ^utm_medium.*  [NC,OR]
    RewriteCond %{REQUEST_FILENAME} ^utm_campaign.*  [NC,OR]
    RewriteCond %{REQUEST_FILENAME} ^utm_content.*  [NC]
    #
    RewriteCond %{REQUEST_FILENAME} !\/blog\/.*  [NC,OR]
    RewriteCond %{REQUEST_FILENAME} !gif.*  [NC,OR]
    RewriteCond %{REQUEST_FILENAME} !jpg.*  [NC]
    RewriteRule ^.*? index.html [R=301,L]
</IfModule>

リダイレクトしたいプライマリURLは次のとおりです。 *http://example.com=> http://example.com/index.html * http://example.com/ = >
http // example。 com / index.html * http://example.com/?utm_source=michael => http://example.com/index.html * http://example.com/?utm_medium=twitter => http:// example.com/index.html * http://example.com/?utm_campaign=camp2&utm_content=somewhere => http://example.com/index.html * http://example.com/blog/*= >いいえリダイレクション * http://example.com/myfile.jpg





=>リダイレクトなし
* http://example.com/myfile.gif= >リダイレクトなし

このリダイレクトは、(ユーザーエージェントが「BotOne」)または(ユーザーエージェントが「OtherBot」)または(彼/彼女のCookie user_idが1でない場合)に発生します。

クエリパラメータはすべて削除されます。

4

1 に答える 1

0

ルールが .htaccess で処理される方法は、プログラミング言語で行う方法と同様に、ある種の構成または解析でこれを表現する方法がまったくありません。過去にも同様の質問があり、完全な回答を得るのに非常に苦労したため、最終的に答えを見つけたとき、将来再び見つけることができるように自分用に書き留めました. これが私が自分自身に書いたものです:

## After quite a bit of puzzlement and seemingly maddeningly
##  vague documentation, I finally figured out exactly how mod_rewrite's
##  [OR] flag really works: In mod_rewrite there's not really any
##  "precendence"; RewriteCond's are simply processed sequentially.
##  Without any modification, the default is to AND _everything_.
##  Including the [OR] modifier on some RewriteCond's creates a
##  two-level expression with only ANDs at the outer/upper level and
##  only ORs at the inner/lower level. Thus
##  RewriteCond a [OR]
##  RewriteCond b
##  RewriteCond c [OR]
##  RewriteCond d
##  RewriteCond e [OR]
##  RewriteCond f [OR]
##  RewriteCond g
##  is equivalent to the boolean expression
##  ((a OR b) AND (c OR d) AND (e OR f OR g))
## There's _no_ way to have ANDs at the _lower/inner_ level and ORs
##  at the _upper/outer_ level; such constructs can only be implemented with
##  either multiple rulesets (and unavoidable duplication), or the
##  introduction of intermediate environment variables.
## Thus the only advantages of [OR] over a | in an RE are increased
##  clarity/maintainability, and the possibility of checking against
##  unrelated variables. REs with lots of |, on the other hand, are
##  assumed to be much faster.

私があなたの必要性を正しく理解していれば、全体は、次のように、補助的な 'if' 句ではなく AND で接続されたブロックを持つ 1 つの巨大な条件付きと考えることができます。

IF

((- HTTP_USER_AGENT includes BotOne
- or HTTP_USER_AGENT includes OtherBot
- or HTTP_COOKIE user_id != 1)
AND
(- REQUEST_URI is "/" main directory
- or REQUEST_FILENAME includes "utm_source"
- or REQUEST_FILENAME includes "utm_medium"
- or REQUEST_FILENAME includes "utm_campaign" and "utm_content")
AND
(- REQUEST_FILENAME doesn't include "/blog/"
- or REQUEST_FILENAME doesn't include "gif"
- or REQUEST_FILENAME doesn't include "jpg"))

THEN

- RewriteRule all files to index.html

私が見る最大の複雑さは、「utm_campaign」と「utm_content」の両方に関するルールです。これは、私の知る限り、正規表現 (.htaccess のような複雑な PERL スタイルのものでさえ) が未指定の順序をまったくうまく処理しないためです。 . 文字列が実際に常に同じ順序になることがわかっている場合は、「utm_campaign.*utm_content」のような RE を作成できます。順序が実際に指定されていない場合、仕様を正確に満たすには、可能な順序ごとに 1 つずつ、次のような2 つのルール条件が必要になります。

RewriteCond "utm_campaign.*utm_content" [OR]
RewriteCond "utm_content.*utm_campaign"

RE の中には、疑似ルールが実際に言っていることとまったく同じものを表現していないように思えます。例えば:

REQUEST_FILENAME includes "utm_source"

なるべき

RewriteCond ${REQUEST_FILENAME} utm_source

なぜなら

RewriteCond ${REQUEST_FILENAME} ^utm_source 

実際に実装する

REQUEST_FILENAME **startswith** utm_source

また、以下のように、ルートをまったく何も送信しない奇妙なブラウザーを許可します (「/」の大文字と小文字のバージョンが別々にないため、[NC] はわずかなパフォーマンス ヒットを与えるだけです)。正当な理由はありません)。また、文字列アンカーの先頭 ('^') と末尾 ('$') が必要であることに注意してください。そうしないと、スラッシュが含まれているため、"/xxx/yyy/zzz" などにも一致します。

RewriteCond ${REQUEST_URI} ^/?$ [OR]

最後に、関心のある文字列の部分のみを一致させます。文字列の残りの部分と一致させる必要はありません (実際、文字列の残りの部分と一致させようとすると、奇妙な不必要なエラーが発生することがよくあります)。言い換えれば、.htaccess RE に ".*" が存在することは、通常、せいぜいパフォーマンスを低下させ、最悪の場合、いくつかのエラーを隠してしまう不必要な奇妙さを示しています。「utm_source.*」ではなく、単に「utm_source」と言ってください。

一見したところ、複数の条件を使用したロジックは私には正しいように見えます (幸いなことに、これらのごちゃ混ぜのような複雑な条件を取得する方法はたくさんあるからです)。したがって、うまくいかない場合は、ロジック/優先順位エラーではなく、ルール (特に正規表現) に他の問題があると思われます。(また、私の推測では、問題には 1 つの共通の根本原因ではなく、いくつかの異なる原因があるため、1 つの問題を修正しても他のすべての問題が修正されるとは限りません。)

入力文字列の具体的な例を1 つ挙げてください。何が起こると予想され、実際に何が起こるのでしょうか?

于 2013-03-09T04:01:40.930 に答える